wao 0.41.3 → 0.41.5
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/.babelrc-cjs +5 -0
- package/.babelrc-esm +5 -0
- package/.gitmodules +4 -0
- package/.prettierrc +6 -0
- package/README.md +90 -0
- package/app/.eslintrc.json +3 -0
- package/app/.mocharc.cjs +6 -0
- package/app/arweave.mjs +87 -0
- package/app/components/Footer.js +76 -0
- package/app/components/Global.js +1128 -0
- package/app/components/Header.js +306 -0
- package/app/components/Left.js +28 -0
- package/app/components/Logo.js +34 -0
- package/app/components/Middle.js +37 -0
- package/app/components/Sidebar.js +93 -0
- package/app/components/Tags.js +42 -0
- package/app/components/editor/Editor.js +322 -0
- package/app/components/editor/FilePath.js +42 -0
- package/app/components/editor/MonacoEditor.js +44 -0
- package/app/components/left/LeftMessages.js +85 -0
- package/app/components/left/LeftModules.js +86 -0
- package/app/components/left/LeftNetworks.js +438 -0
- package/app/components/left/LeftProcesses.js +98 -0
- package/app/components/left/LeftProjects.js +397 -0
- package/app/components/left/LeftTests.js +189 -0
- package/app/components/middle/MiddleBlocks.js +79 -0
- package/app/components/middle/MiddleEntity.js +16 -0
- package/app/components/middle/MiddleEntityAccount.js +264 -0
- package/app/components/middle/MiddleEntityAssignment.js +104 -0
- package/app/components/middle/MiddleEntityBlock.js +148 -0
- package/app/components/middle/MiddleEntityMessage.js +430 -0
- package/app/components/middle/MiddleEntityModule.js +183 -0
- package/app/components/middle/MiddleEntityProcess.js +323 -0
- package/app/components/middle/MiddleEntityTx.js +211 -0
- package/app/components/middle/MiddleMessages.js +87 -0
- package/app/components/middle/MiddleModules.js +89 -0
- package/app/components/middle/MiddleNetworks.js +516 -0
- package/app/components/middle/MiddleProcesses.js +87 -0
- package/app/components/middle/MiddleTests.js +134 -0
- package/app/components/modals/CreateFileModal.js +115 -0
- package/app/components/modals/CreateFolderModal.js +83 -0
- package/app/components/modals/CreateProjectModal.js +63 -0
- package/app/components/modals/FSModal.js +141 -0
- package/app/components/modals/ImportModal.js +105 -0
- package/app/components/modals/LaunchNetworkModal.js +95 -0
- package/app/components/modals/Modal.js +38 -0
- package/app/components/modals/ProxyModal.js +122 -0
- package/app/components/modals/RenameFileModal.js +95 -0
- package/app/components/styles/EditorScrollbarStyle.js +29 -0
- package/app/components/styles/EntityScrollbarStyle.js +29 -0
- package/app/components/styles/GlobalStyle.js +102 -0
- package/app/components/styles/XtermStyle.js +37 -0
- package/app/components/terminal/Terminal.js +132 -0
- package/app/components/terminal/Xterm.js +160 -0
- package/app/components/ui/avatar.jsx +49 -0
- package/app/components/ui/checkbox.jsx +17 -0
- package/app/components/ui/close-button.jsx +20 -0
- package/app/components/ui/color-mode.jsx +61 -0
- package/app/components/ui/dialog.jsx +54 -0
- package/app/components/ui/drawer.jsx +44 -0
- package/app/components/ui/field.jsx +22 -0
- package/app/components/ui/input-group.jsx +39 -0
- package/app/components/ui/popover.jsx +49 -0
- package/app/components/ui/provider.jsx +12 -0
- package/app/components/ui/radio.jsx +17 -0
- package/app/components/ui/slider.jsx +107 -0
- package/app/components/ui/toaster.jsx +69 -0
- package/app/components/ui/tooltip.jsx +35 -0
- package/app/index.js +10 -0
- package/app/jsconfig.json +7 -0
- package/app/lib/GithubCSS.js +1218 -0
- package/app/lib/addon-fit.js +72 -0
- package/app/lib/data.js +31 -0
- package/app/lib/github-markdown.css +1169 -0
- package/app/lib/global.js +1 -0
- package/app/lib/guide.js +82 -0
- package/app/lib/hub.js +109 -0
- package/app/lib/scripts.js +47 -0
- package/app/lib/store.js +34 -0
- package/app/lib/use.js +64 -0
- package/app/lib/utils.js +387 -0
- package/app/lib/webrtc.js +217 -0
- package/app/next.config.js +25 -0
- package/app/package.json +62 -0
- package/app/pages/404.js +9 -0
- package/app/pages/_app.js +10 -0
- package/app/pages/_document.js +14 -0
- package/app/pages/index.js +121 -0
- package/app/playwright.config.mjs +41 -0
- package/app/proxy.mjs +21 -0
- package/app/public/assets/cover.png +0 -0
- package/app/public/blueprints/apm.lua +91 -0
- package/app/public/blueprints/arena.lua +345 -0
- package/app/public/blueprints/arns.lua +318 -0
- package/app/public/blueprints/chat.lua +210 -0
- package/app/public/blueprints/chatroom.lua +56 -0
- package/app/public/blueprints/patch-legacy-reply.lua +13 -0
- package/app/public/blueprints/staking.lua +93 -0
- package/app/public/blueprints/token.lua +298 -0
- package/app/public/blueprints/voting.lua +45 -0
- package/app/public/favicon.ico +0 -0
- package/app/public/logo.png +0 -0
- package/cli-esm.js +55 -0
- package/cli.js +54 -0
- package/devnet/app/api.js +129 -0
- package/devnet/app/components/layout.js +89 -0
- package/devnet/app/components/pagination.js +144 -0
- package/devnet/app/components/search.js +159 -0
- package/devnet/app/components/table.js +124 -0
- package/devnet/app/components/tags.js +89 -0
- package/devnet/app/index.html +14 -0
- package/devnet/app/main.js +215 -0
- package/devnet/app/router.js +59 -0
- package/devnet/app/state.js +19 -0
- package/devnet/app/style.css +1606 -0
- package/devnet/app/utils.js +77 -0
- package/devnet/app/views/blocks.js +75 -0
- package/devnet/app/views/dashboard.js +127 -0
- package/devnet/app/views/entity.js +1473 -0
- package/devnet/app/views/messages.js +90 -0
- package/devnet/app/views/modules.js +165 -0
- package/devnet/app/views/processes.js +90 -0
- package/devnet/app/views/schedulers.js +90 -0
- package/devnet/app/views/transactions.js +88 -0
- package/devnet/migrations/0001_initial.sql +51 -0
- package/devnet/package.json +26 -0
- package/devnet/playwright.config.js +7 -0
- package/devnet/src/cu-worker.js +166 -0
- package/devnet/src/index.js +309 -0
- package/devnet/vite.config.js +17 -0
- package/devnet/vitest.config.js +10 -0
- package/devnet/wrangler-cu.toml +32 -0
- package/devnet/wrangler.toml +38 -0
- package/dhfs-tutorial-app/package.json +15 -0
- package/dist/esm/workspace/dashboard/public/favicon.png +0 -0
- package/dist/esm/workspace/src/counter.lua +14 -0
- package/dist/package.json +82 -0
- package/hb.sh +18 -0
- package/hbsig/.babelrc-cjs +5 -0
- package/hbsig/.babelrc-esm +5 -0
- package/hbsig/README.md +1 -0
- package/hbsig/dist/cjs/bin_to_str.js +44 -0
- package/hbsig/dist/cjs/collect-body-keys.js +470 -0
- package/hbsig/dist/cjs/commit.js +330 -0
- package/hbsig/dist/cjs/encode-array-item.js +110 -0
- package/hbsig/dist/cjs/encode-utils.js +242 -0
- package/hbsig/dist/cjs/encode.js +1365 -0
- package/hbsig/dist/cjs/erl_json.js +326 -0
- package/hbsig/dist/cjs/erl_str.js +1042 -0
- package/hbsig/dist/cjs/flat.js +279 -0
- package/hbsig/dist/cjs/http-message-signatures/httpbis.js +489 -0
- package/hbsig/dist/cjs/http-message-signatures/index.js +25 -0
- package/hbsig/dist/cjs/http-message-signatures/structured-header.js +129 -0
- package/hbsig/dist/cjs/httpsig.js +861 -0
- package/hbsig/dist/cjs/id.js +470 -0
- package/hbsig/dist/cjs/index.js +174 -0
- package/hbsig/dist/cjs/nocrypto.js +51 -0
- package/hbsig/dist/cjs/parser.js +201 -0
- package/hbsig/dist/cjs/send-utils.js +1231 -0
- package/hbsig/dist/cjs/send.js +211 -0
- package/hbsig/dist/cjs/signer-utils.js +494 -0
- package/hbsig/dist/cjs/signer.js +436 -0
- package/hbsig/dist/cjs/structured.js +515 -0
- package/hbsig/dist/cjs/test.js +12 -0
- package/hbsig/dist/cjs/utils.js +44 -0
- package/hbsig/dist/esm/bin_to_str.js +46 -0
- package/hbsig/dist/esm/collect-body-keys.js +436 -0
- package/hbsig/dist/esm/commit.js +219 -0
- package/hbsig/dist/esm/encode-array-item.js +112 -0
- package/hbsig/dist/esm/encode-utils.js +191 -0
- package/hbsig/dist/esm/encode.js +1256 -0
- package/hbsig/dist/esm/erl_json.js +292 -0
- package/hbsig/dist/esm/erl_str.js +1144 -0
- package/hbsig/dist/esm/flat.js +250 -0
- package/hbsig/dist/esm/http-message-signatures/httpbis.js +438 -0
- package/hbsig/dist/esm/http-message-signatures/index.js +4 -0
- package/hbsig/dist/esm/http-message-signatures/structured-header.js +105 -0
- package/hbsig/dist/esm/httpsig.js +866 -0
- package/hbsig/dist/esm/id.js +459 -0
- package/hbsig/dist/esm/index.js +13 -0
- package/hbsig/dist/esm/nocrypto.js +4 -0
- package/hbsig/dist/esm/package.json +3 -0
- package/hbsig/dist/esm/parser.js +171 -0
- package/hbsig/dist/esm/send-utils.js +1132 -0
- package/hbsig/dist/esm/send.js +142 -0
- package/hbsig/dist/esm/signer-utils.js +375 -0
- package/hbsig/dist/esm/signer.js +312 -0
- package/hbsig/dist/esm/structured.js +496 -0
- package/hbsig/dist/esm/test.js +2 -0
- package/hbsig/dist/esm/utils.js +29 -0
- package/hbsig/dist/package.json +39 -0
- package/hbsig/make.js +36 -0
- package/hbsig/package.json +39 -0
- package/hbsig/src/bin_to_str.js +46 -0
- package/hbsig/src/collect-body-keys.js +436 -0
- package/hbsig/src/commit.js +219 -0
- package/hbsig/src/encode-array-item.js +112 -0
- package/hbsig/src/encode-utils.js +191 -0
- package/hbsig/src/encode.js +1256 -0
- package/hbsig/src/erl_json.js +292 -0
- package/hbsig/src/erl_str.js +1144 -0
- package/hbsig/src/flat.js +250 -0
- package/hbsig/src/http-message-signatures/httpbis.js +438 -0
- package/hbsig/src/http-message-signatures/index.js +4 -0
- package/hbsig/src/http-message-signatures/structured-header.js +105 -0
- package/hbsig/src/httpsig.js +866 -0
- package/hbsig/src/id.js +459 -0
- package/hbsig/src/index.js +13 -0
- package/hbsig/src/nocrypto.js +4 -0
- package/hbsig/src/parser.js +171 -0
- package/hbsig/src/send-utils.js +1132 -0
- package/hbsig/src/send.js +142 -0
- package/hbsig/src/signer-utils.js +375 -0
- package/hbsig/src/signer.js +312 -0
- package/hbsig/src/structured.js +496 -0
- package/hbsig/src/test.js +2 -0
- package/hbsig/src/utils.js +29 -0
- package/lp/index.html +25 -0
- package/lp/package.json +19 -0
- package/lp/public/cover.png +0 -0
- package/lp/public/favicon.ico +0 -0
- package/lp/public/favicon.png +0 -0
- package/lp/public/images/book.jpg +0 -0
- package/lp/public/images/dashboard.png +0 -0
- package/lp/public/images/devnet.png +0 -0
- package/lp/public/images/hero-bg.png +0 -0
- package/lp/public/images/hyperadd.png +0 -0
- package/lp/public/images/message-flow.png +0 -0
- package/lp/public/images/mobile.png +0 -0
- package/lp/public/images/og-cover.png +0 -0
- package/lp/public/images/scan.png +0 -0
- package/lp/public/images/wao-hub.png +0 -0
- package/lp/public/images/wao-web.png +0 -0
- package/lp/public/logo.png +0 -0
- package/lp/src/App.jsx +29 -0
- package/lp/src/components/CodeBlock.jsx +37 -0
- package/lp/src/components/CodeBlock.module.css +89 -0
- package/lp/src/components/Footer.jsx +22 -0
- package/lp/src/components/Footer.module.css +60 -0
- package/lp/src/components/Nav.jsx +80 -0
- package/lp/src/components/Nav.module.css +177 -0
- package/lp/src/components/SectionWrapper.jsx +15 -0
- package/lp/src/hooks/useReveal.js +25 -0
- package/lp/src/hooks/useScrolled.js +14 -0
- package/lp/src/main.jsx +10 -0
- package/lp/src/sections/Book.jsx +60 -0
- package/lp/src/sections/Book.module.css +204 -0
- package/lp/src/sections/Browser.jsx +46 -0
- package/lp/src/sections/Browser.module.css +67 -0
- package/lp/src/sections/Devnet.jsx +55 -0
- package/lp/src/sections/Devnet.module.css +136 -0
- package/lp/src/sections/GetStarted.jsx +51 -0
- package/lp/src/sections/GetStarted.module.css +128 -0
- package/lp/src/sections/Hero.jsx +67 -0
- package/lp/src/sections/Hero.module.css +202 -0
- package/lp/src/sections/HyperADD.jsx +46 -0
- package/lp/src/sections/HyperADD.module.css +113 -0
- package/lp/src/sections/SDK.jsx +90 -0
- package/lp/src/sections/SDK.module.css +122 -0
- package/lp/src/sections/Testing.jsx +47 -0
- package/lp/src/sections/Testing.module.css +124 -0
- package/lp/src/sections/Vision.jsx +93 -0
- package/lp/src/sections/Vision.module.css +147 -0
- package/lp/src/styles/globals.css +285 -0
- package/lp/src/utils/scrollTo.js +4 -0
- package/lp/vite.config.js +7 -0
- package/make.js +39 -0
- package/package.json +17 -12
- package/patches/@permaweb+ao-loader+0.0.44.patch +64 -0
- package/plan.md +435 -0
- package/rebar.lock +1 -0
- package/src/accounts-web.js +128 -0
- package/src/accounts.js +124 -0
- package/src/adaptor-base.js +622 -0
- package/src/adaptor-cf.js +11 -0
- package/src/adaptor-web.js +11 -0
- package/src/adaptor.js +10 -0
- package/src/ao-loader.js +30660 -0
- package/src/ao.js +1173 -0
- package/src/aoconnect-base.js +1098 -0
- package/src/aoconnect-cf.js +9 -0
- package/src/aoconnect-web.js +8 -0
- package/src/aoconnect.js +8 -0
- package/src/aos_wamr.js +1 -0
- package/src/ar-remote.js +87 -0
- package/src/ar.js +276 -0
- package/src/armem-base.js +529 -0
- package/src/armem-cf.js +67 -0
- package/src/armem-web.js +19 -0
- package/src/armem.js +26 -0
- package/src/bao.js +141 -0
- package/src/bar.js +366 -0
- package/src/build.js +7 -0
- package/src/bundler.js +119 -0
- package/src/car.js +10 -0
- package/src/cf-env.js +29 -0
- package/src/cf.js +11 -0
- package/src/cli.js +561 -0
- package/src/compress.js +112 -0
- package/src/create.js +415 -0
- package/src/devs.js +86 -0
- package/src/dirname.js +1 -0
- package/src/dodb.js +26 -0
- package/src/erl_json.js +289 -0
- package/src/erl_str.js +1139 -0
- package/src/gql.js +229 -0
- package/src/hb.js +967 -0
- package/src/helpers.js +203 -0
- package/src/http.js +619 -0
- package/src/hub/bundler.js +123 -0
- package/src/hub/cu.js +74 -0
- package/src/hub/fs.js +157 -0
- package/src/hub/index.js +85 -0
- package/src/hub/utils.js +64 -0
- package/src/hub/ws-proxy.js +67 -0
- package/src/hyper-aos.js +1 -0
- package/src/hyperbeam-server.js +21 -0
- package/src/hyperbeam.js +585 -0
- package/src/index.js +5 -0
- package/src/keygen.js +47 -0
- package/src/lfdb.js +67 -0
- package/src/lua/aos.wasm +0 -0
- package/src/lua/aos2_0_1.js +1 -0
- package/src/lua/aos2_0_1.wasm +0 -0
- package/src/lua/aos2_0_3.js +1 -0
- package/src/lua/aos2_0_3.wasm +0 -0
- package/src/lua/aos2_0_4_32.js +1 -0
- package/src/lua/aos2_0_4_32.wasm +0 -0
- package/src/lua/aos2_0_6.wasm +0 -0
- package/src/lua/apm.lua +61 -0
- package/src/lua/llama.wasm +0 -0
- package/src/lua/process.wasm +0 -0
- package/src/lua/sqlite.js +1 -0
- package/src/lua/sqlite.wasm +0 -0
- package/src/lua/weavedb_mock.lua +44 -0
- package/src/lua/weavedrive.lua +53 -0
- package/src/run.js +25 -0
- package/src/server.js +173 -0
- package/src/storage-multi.js +183 -0
- package/src/tao.js +12 -0
- package/src/tar.js +10 -0
- package/src/test.js +42 -0
- package/src/tgql-d1.js +407 -0
- package/src/tgql.js +310 -0
- package/src/toerl.js +162 -0
- package/src/utils.js +777 -0
- package/src/wao.js +29 -0
- package/src/waosm/README.md +81 -0
- package/src/waosm/waosm.d.ts +40 -0
- package/src/waosm/waosm.js +240 -0
- package/src/waosm/waosm_bg.wasm +0 -0
- package/src/waosm/waosm_bg.wasm.d.ts +8 -0
- package/src/waosm-node/README.md +81 -0
- package/src/waosm-node/waosm.d.ts +8 -0
- package/src/waosm-node/waosm.js +4 -0
- package/src/waosm-node/waosm_bg.js +147 -0
- package/src/waosm-node/waosm_bg.wasm +0 -0
- package/src/waosm-node/waosm_bg.wasm.d.ts +8 -0
- package/src/waosm-node/waosm_bg.wasm.js +14 -0
- package/src/waosm-node.js +9 -0
- package/src/war.js +10 -0
- package/src/weavedrive.js +376 -0
- package/src/web.js +11 -0
- package/src/workspace/.mcp.json +8 -0
- package/src/workspace/CLAUDE.md +258 -0
- package/src/workspace/README.md +85 -0
- package/src/workspace/dashboard/index.html +163 -0
- package/src/workspace/dashboard/package.json +18 -0
- package/src/workspace/dashboard/public/favicon.ico +0 -0
- package/src/workspace/dashboard/public/favicon.png +0 -0
- package/src/workspace/dashboard/server.js +224 -0
- package/src/workspace/dashboard/src/App.jsx +2350 -0
- package/{cjs/workspace/frontend → src/workspace/dashboard}/vite.config.js +6 -0
- package/src/workspace/package.json +18 -0
- package/src/workspace/src/counter.lua +14 -0
- package/tsconfig.json +18 -0
- package/types/index.d.ts +329 -0
- package/waollama/.eslintrc.json +3 -0
- package/waollama/README.md +19 -0
- package/waollama/arweave.mjs +87 -0
- package/waollama/components/ui/avatar.jsx +49 -0
- package/waollama/components/ui/checkbox.jsx +17 -0
- package/waollama/components/ui/close-button.jsx +20 -0
- package/waollama/components/ui/color-mode.jsx +61 -0
- package/waollama/components/ui/dialog.jsx +54 -0
- package/waollama/components/ui/drawer.jsx +44 -0
- package/waollama/components/ui/field.jsx +22 -0
- package/waollama/components/ui/input-group.jsx +39 -0
- package/waollama/components/ui/popover.jsx +49 -0
- package/waollama/components/ui/provider.jsx +12 -0
- package/waollama/components/ui/radio.jsx +17 -0
- package/waollama/components/ui/slider.jsx +107 -0
- package/waollama/components/ui/tooltip.jsx +35 -0
- package/waollama/index.js +10 -0
- package/waollama/jsconfig.json +7 -0
- package/waollama/lib/ao-loader.js +30654 -0
- package/waollama/lib/client.js +1 -0
- package/waollama/lib/wasm.js +1 -0
- package/waollama/next.config.js +25 -0
- package/waollama/package.json +43 -0
- package/waollama/pages/404.js +9 -0
- package/waollama/pages/_app.js +9 -0
- package/waollama/pages/_document.js +14 -0
- package/waollama/pages/index.js +212 -0
- package/waollama/playwright.config.js +31 -0
- package/waollama/proxy.mjs +21 -0
- package/waollama/public/favicon.ico +0 -0
- package/waollama/public/human.png +0 -0
- package/waollama/public/llama.png +0 -0
- package/waosm/Cargo.toml +11 -0
- package/waosm/README.md +81 -0
- package/waosm/compress.js +112 -0
- package/waosm/make.js +33 -0
- package/waosm/package.json +10 -0
- package/waosm/src/lib.rs +180 -0
- package/waosm/test.js +16 -0
- package/cjs/workspace/.claude/agents/builder.md +0 -99
- package/cjs/workspace/.claude/agents/device-builder.md +0 -86
- package/cjs/workspace/.claude/agents/tester.md +0 -90
- package/cjs/workspace/.claude/mcp/dashboard/server.js +0 -128
- package/cjs/workspace/.claude/rules/deploy.md +0 -45
- package/cjs/workspace/.claude/rules/frontend.md +0 -69
- package/cjs/workspace/.claude/rules/hyperbeam.md +0 -104
- package/cjs/workspace/.claude/rules/lua.md +0 -108
- package/cjs/workspace/.claude/rules/testing.md +0 -257
- package/cjs/workspace/.claude/settings.json +0 -109
- package/cjs/workspace/.claude/skills/build/SKILL.md +0 -214
- package/cjs/workspace/.claude/skills/build-aos/SKILL.md +0 -129
- package/cjs/workspace/.claude/skills/build-device/SKILL.md +0 -192
- package/cjs/workspace/.claude/skills/build-frontend/SKILL.md +0 -134
- package/cjs/workspace/.claude/skills/build-module/SKILL.md +0 -281
- package/cjs/workspace/.claude/skills/create-aos/SKILL.md +0 -63
- package/cjs/workspace/.claude/skills/create-device/SKILL.md +0 -87
- package/cjs/workspace/.claude/skills/create-module/SKILL.md +0 -162
- package/cjs/workspace/.claude/skills/debug/SKILL.md +0 -57
- package/cjs/workspace/.claude/skills/deploy/SKILL.md +0 -85
- package/cjs/workspace/.claude/skills/dev/SKILL.md +0 -32
- package/cjs/workspace/.claude/skills/plan/SKILL.md +0 -176
- package/cjs/workspace/.claude/skills/readme/SKILL.md +0 -186
- package/cjs/workspace/.claude/skills/report/SKILL.md +0 -49
- package/cjs/workspace/.claude/skills/team/SKILL.md +0 -101
- package/cjs/workspace/.claude/skills/test/SKILL.md +0 -56
- package/cjs/workspace/.claude/skills/test-device/SKILL.md +0 -114
- package/cjs/workspace/.claude/skills/test-e2e/SKILL.md +0 -103
- package/cjs/workspace/.claude/skills/test-hb/SKILL.md +0 -76
- package/cjs/workspace/.claude/skills/validate/SKILL.md +0 -96
- package/cjs/workspace/.claude/skills/validate/scripts/check-lua.sh +0 -41
- package/cjs/workspace/docs/aos-lua.md +0 -428
- package/cjs/workspace/docs/debug.md +0 -230
- package/cjs/workspace/docs/hyperbeam-dev.md +0 -606
- package/cjs/workspace/docs/hyperbeam-devices.md +0 -618
- package/cjs/workspace/docs/wao-sdk.md +0 -807
- package/cjs/workspace/frontend/e2e/.gitkeep +0 -0
- package/cjs/workspace/frontend/index.html +0 -12
- package/cjs/workspace/frontend/package.json +0 -24
- package/cjs/workspace/frontend/playwright.config.js +0 -10
- package/cjs/workspace/frontend/src/App.jsx +0 -24
- package/cjs/workspace/frontend/test/.gitkeep +0 -0
- package/cjs/workspace/frontend/vitest.config.js +0 -10
- package/cjs/workspace/scripts/deploy.js +0 -140
- package/cjs/workspace/scripts/keygen.js +0 -52
- package/cjs/workspace/test/aos.test.js +0 -98
- package/cjs/workspace/test/hyperbeam.test.js +0 -80
- package/esm/compiler/native +0 -0
- package/esm/workspace/.claude/agents/builder.md +0 -99
- package/esm/workspace/.claude/agents/device-builder.md +0 -86
- package/esm/workspace/.claude/agents/tester.md +0 -90
- package/esm/workspace/.claude/mcp/dashboard/server.js +0 -128
- package/esm/workspace/.claude/rules/deploy.md +0 -45
- package/esm/workspace/.claude/rules/frontend.md +0 -69
- package/esm/workspace/.claude/rules/hyperbeam.md +0 -104
- package/esm/workspace/.claude/rules/lua.md +0 -108
- package/esm/workspace/.claude/rules/testing.md +0 -257
- package/esm/workspace/.claude/settings.json +0 -109
- package/esm/workspace/.claude/skills/build/SKILL.md +0 -214
- package/esm/workspace/.claude/skills/build-aos/SKILL.md +0 -129
- package/esm/workspace/.claude/skills/build-device/SKILL.md +0 -192
- package/esm/workspace/.claude/skills/build-frontend/SKILL.md +0 -134
- package/esm/workspace/.claude/skills/build-module/SKILL.md +0 -281
- package/esm/workspace/.claude/skills/create-aos/SKILL.md +0 -63
- package/esm/workspace/.claude/skills/create-device/SKILL.md +0 -87
- package/esm/workspace/.claude/skills/create-module/SKILL.md +0 -162
- package/esm/workspace/.claude/skills/debug/SKILL.md +0 -57
- package/esm/workspace/.claude/skills/deploy/SKILL.md +0 -85
- package/esm/workspace/.claude/skills/dev/SKILL.md +0 -32
- package/esm/workspace/.claude/skills/plan/SKILL.md +0 -176
- package/esm/workspace/.claude/skills/readme/SKILL.md +0 -186
- package/esm/workspace/.claude/skills/report/SKILL.md +0 -49
- package/esm/workspace/.claude/skills/team/SKILL.md +0 -101
- package/esm/workspace/.claude/skills/test/SKILL.md +0 -56
- package/esm/workspace/.claude/skills/test-device/SKILL.md +0 -114
- package/esm/workspace/.claude/skills/test-e2e/SKILL.md +0 -103
- package/esm/workspace/.claude/skills/test-hb/SKILL.md +0 -76
- package/esm/workspace/.claude/skills/validate/SKILL.md +0 -96
- package/esm/workspace/.claude/skills/validate/scripts/check-lua.sh +0 -41
- package/esm/workspace/docs/aos-lua.md +0 -428
- package/esm/workspace/docs/debug.md +0 -230
- package/esm/workspace/docs/hyperbeam-dev.md +0 -606
- package/esm/workspace/docs/hyperbeam-devices.md +0 -618
- package/esm/workspace/docs/wao-sdk.md +0 -807
- package/esm/workspace/frontend/e2e/.gitkeep +0 -0
- package/esm/workspace/frontend/index.html +0 -12
- package/esm/workspace/frontend/package.json +0 -24
- package/esm/workspace/frontend/playwright.config.js +0 -10
- package/esm/workspace/frontend/src/App.jsx +0 -24
- package/esm/workspace/frontend/src/main.jsx +0 -9
- package/esm/workspace/frontend/test/.gitkeep +0 -0
- package/esm/workspace/frontend/vite.config.js +0 -6
- package/esm/workspace/frontend/vitest.config.js +0 -10
- package/esm/workspace/scripts/deploy.js +0 -140
- package/esm/workspace/scripts/keygen.js +0 -52
- package/esm/workspace/test/aos.test.js +0 -98
- package/esm/workspace/test/hyperbeam.test.js +0 -80
- /package/{cjs/workspace/dashboard/public → devnet/app}/favicon.ico +0 -0
- /package/{cjs/workspace → dhfs-tutorial-app}/src/counter.lua +0 -0
- /package/{cjs → dist/cjs}/accounts-web.js +0 -0
- /package/{cjs → dist/cjs}/accounts.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-base.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-cf.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-web.js +0 -0
- /package/{cjs → dist/cjs}/adaptor.js +0 -0
- /package/{cjs → dist/cjs}/ao-loader.js +0 -0
- /package/{cjs → dist/cjs}/ao.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-base.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-cf.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-web.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect.js +0 -0
- /package/{cjs → dist/cjs}/aos_wamr.js +0 -0
- /package/{cjs → dist/cjs}/ar-remote.js +0 -0
- /package/{cjs → dist/cjs}/ar.js +0 -0
- /package/{cjs → dist/cjs}/armem-base.js +0 -0
- /package/{cjs → dist/cjs}/armem-cf.js +0 -0
- /package/{cjs → dist/cjs}/armem-web.js +0 -0
- /package/{cjs → dist/cjs}/armem.js +0 -0
- /package/{cjs → dist/cjs}/bao.js +0 -0
- /package/{cjs → dist/cjs}/bar.js +0 -0
- /package/{cjs → dist/cjs}/build.js +0 -0
- /package/{cjs → dist/cjs}/bundler.js +0 -0
- /package/{cjs → dist/cjs}/car.js +0 -0
- /package/{cjs → dist/cjs}/cf-env.js +0 -0
- /package/{cjs → dist/cjs}/cf.js +0 -0
- /package/{cjs → dist/cjs}/cli.js +0 -0
- /package/{cjs → dist/cjs}/compress.js +0 -0
- /package/{cjs → dist/cjs}/create.js +0 -0
- /package/{cjs → dist/cjs}/devs.js +0 -0
- /package/{cjs → dist/cjs}/dirname.js +0 -0
- /package/{cjs → dist/cjs}/dodb.js +0 -0
- /package/{cjs → dist/cjs}/erl_json.js +0 -0
- /package/{cjs → dist/cjs}/erl_str.js +0 -0
- /package/{cjs → dist/cjs}/gql.js +0 -0
- /package/{cjs → dist/cjs}/hb.js +0 -0
- /package/{cjs → dist/cjs}/helpers.js +0 -0
- /package/{cjs → dist/cjs}/http.js +0 -0
- /package/{cjs → dist/cjs}/hub/bundler.js +0 -0
- /package/{cjs → dist/cjs}/hub/cu.js +0 -0
- /package/{cjs → dist/cjs}/hub/fs.js +0 -0
- /package/{cjs → dist/cjs}/hub/index.js +0 -0
- /package/{cjs → dist/cjs}/hub/utils.js +0 -0
- /package/{cjs → dist/cjs}/hub/ws-proxy.js +0 -0
- /package/{cjs → dist/cjs}/hyper-aos.js +0 -0
- /package/{cjs → dist/cjs}/hyperbeam-server.js +0 -0
- /package/{cjs → dist/cjs}/hyperbeam.js +0 -0
- /package/{cjs → dist/cjs}/index.js +0 -0
- /package/{cjs → dist/cjs}/keygen.js +0 -0
- /package/{cjs → dist/cjs}/lfdb.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_1.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_1.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_3.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_3.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_4_32.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_4_32.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_6.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/apm.lua +0 -0
- /package/{cjs → dist/cjs}/lua/llama.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/process.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/sqlite.js +0 -0
- /package/{cjs → dist/cjs}/lua/sqlite.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/weavedb_mock.lua +0 -0
- /package/{cjs → dist/cjs}/lua/weavedrive.lua +0 -0
- /package/{cjs → dist/cjs}/run.js +0 -0
- /package/{cjs → dist/cjs}/server.js +0 -0
- /package/{cjs → dist/cjs}/storage-multi.js +0 -0
- /package/{cjs → dist/cjs}/tao.js +0 -0
- /package/{cjs → dist/cjs}/tar.js +0 -0
- /package/{cjs → dist/cjs}/test.js +0 -0
- /package/{cjs → dist/cjs}/tgql-d1.js +0 -0
- /package/{cjs → dist/cjs}/tgql.js +0 -0
- /package/{cjs → dist/cjs}/toerl.js +0 -0
- /package/{cjs → dist/cjs}/utils.js +0 -0
- /package/{cjs → dist/cjs}/wao.js +0 -0
- /package/{cjs → dist/cjs}/waosm/waosm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.wasm +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.wasm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node.js +0 -0
- /package/{cjs → dist/cjs}/war.js +0 -0
- /package/{cjs → dist/cjs}/weavedrive.js +0 -0
- /package/{cjs → dist/cjs}/web.js +0 -0
- /package/{cjs → dist/cjs}/workspace/.mcp.json +0 -0
- /package/{cjs → dist/cjs}/workspace/CLAUDE.md +0 -0
- /package/{cjs → dist/cjs}/workspace/README.md +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/index.html +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/package.json +0 -0
- /package/{esm → dist/cjs}/workspace/dashboard/public/favicon.ico +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/public/favicon.png +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/server.js +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/src/App.jsx +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/src/main.jsx +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/vite.config.js +0 -0
- /package/{cjs → dist/cjs}/workspace/package.json +0 -0
- /package/{esm → dist/cjs}/workspace/src/counter.lua +0 -0
- /package/{esm → dist/esm}/accounts-web.js +0 -0
- /package/{esm → dist/esm}/accounts.js +0 -0
- /package/{esm → dist/esm}/adaptor-base.js +0 -0
- /package/{esm → dist/esm}/adaptor-cf.js +0 -0
- /package/{esm → dist/esm}/adaptor-web.js +0 -0
- /package/{esm → dist/esm}/adaptor.js +0 -0
- /package/{esm → dist/esm}/ao-loader.js +0 -0
- /package/{esm → dist/esm}/ao.js +0 -0
- /package/{esm → dist/esm}/aoconnect-base.js +0 -0
- /package/{esm → dist/esm}/aoconnect-cf.js +0 -0
- /package/{esm → dist/esm}/aoconnect-web.js +0 -0
- /package/{esm → dist/esm}/aoconnect.js +0 -0
- /package/{esm → dist/esm}/aos_wamr.js +0 -0
- /package/{esm → dist/esm}/ar-remote.js +0 -0
- /package/{esm → dist/esm}/ar.js +0 -0
- /package/{esm → dist/esm}/armem-base.js +0 -0
- /package/{esm → dist/esm}/armem-cf.js +0 -0
- /package/{esm → dist/esm}/armem-web.js +0 -0
- /package/{esm → dist/esm}/armem.js +0 -0
- /package/{esm → dist/esm}/bao.js +0 -0
- /package/{esm → dist/esm}/bar.js +0 -0
- /package/{esm → dist/esm}/build.js +0 -0
- /package/{esm → dist/esm}/bundler.js +0 -0
- /package/{esm → dist/esm}/car.js +0 -0
- /package/{esm → dist/esm}/cf-env.js +0 -0
- /package/{esm → dist/esm}/cf.js +0 -0
- /package/{esm → dist/esm}/cli.js +0 -0
- /package/{esm → dist/esm}/compress.js +0 -0
- /package/{esm → dist/esm}/create.js +0 -0
- /package/{esm → dist/esm}/devs.js +0 -0
- /package/{esm → dist/esm}/dirname.js +0 -0
- /package/{esm → dist/esm}/dodb.js +0 -0
- /package/{esm → dist/esm}/erl_json.js +0 -0
- /package/{esm → dist/esm}/erl_str.js +0 -0
- /package/{esm → dist/esm}/gql.js +0 -0
- /package/{esm → dist/esm}/hb.js +0 -0
- /package/{esm → dist/esm}/helpers.js +0 -0
- /package/{esm → dist/esm}/http.js +0 -0
- /package/{esm → dist/esm}/hub/bundler.js +0 -0
- /package/{esm → dist/esm}/hub/cu.js +0 -0
- /package/{esm → dist/esm}/hub/fs.js +0 -0
- /package/{esm → dist/esm}/hub/index.js +0 -0
- /package/{esm → dist/esm}/hub/utils.js +0 -0
- /package/{esm → dist/esm}/hub/ws-proxy.js +0 -0
- /package/{esm → dist/esm}/hyper-aos.js +0 -0
- /package/{esm → dist/esm}/hyperbeam-server.js +0 -0
- /package/{esm → dist/esm}/hyperbeam.js +0 -0
- /package/{esm → dist/esm}/index.js +0 -0
- /package/{esm → dist/esm}/keygen.js +0 -0
- /package/{esm → dist/esm}/lfdb.js +0 -0
- /package/{esm → dist/esm}/lua/aos.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_1.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_1.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_3.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_3.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_4_32.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_4_32.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_6.wasm +0 -0
- /package/{esm → dist/esm}/lua/apm.lua +0 -0
- /package/{esm → dist/esm}/lua/llama.wasm +0 -0
- /package/{esm → dist/esm}/lua/process.wasm +0 -0
- /package/{esm → dist/esm}/lua/sqlite.js +0 -0
- /package/{esm → dist/esm}/lua/sqlite.wasm +0 -0
- /package/{esm → dist/esm}/lua/weavedb_mock.lua +0 -0
- /package/{esm → dist/esm}/lua/weavedrive.lua +0 -0
- /package/{esm → dist/esm}/package.json +0 -0
- /package/{esm → dist/esm}/run.js +0 -0
- /package/{esm → dist/esm}/server.js +0 -0
- /package/{esm → dist/esm}/storage-multi.js +0 -0
- /package/{esm → dist/esm}/tao.js +0 -0
- /package/{esm → dist/esm}/tar.js +0 -0
- /package/{esm → dist/esm}/test.js +0 -0
- /package/{esm → dist/esm}/tgql-d1.js +0 -0
- /package/{esm → dist/esm}/tgql.js +0 -0
- /package/{esm → dist/esm}/toerl.js +0 -0
- /package/{esm → dist/esm}/utils.js +0 -0
- /package/{esm → dist/esm}/wao.js +0 -0
- /package/{esm → dist/esm}/waosm/README.md +0 -0
- /package/{esm → dist/esm}/waosm/waosm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm/waosm.js +0 -0
- /package/{esm → dist/esm}/waosm/waosm_bg.wasm +0 -0
- /package/{esm → dist/esm}/waosm/waosm_bg.wasm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/README.md +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm.js +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.js +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm.js +0 -0
- /package/{esm → dist/esm}/waosm-node.js +0 -0
- /package/{esm → dist/esm}/war.js +0 -0
- /package/{esm → dist/esm}/weavedrive.js +0 -0
- /package/{esm → dist/esm}/web.js +0 -0
- /package/{esm → dist/esm}/workspace/.mcp.json +0 -0
- /package/{esm → dist/esm}/workspace/CLAUDE.md +0 -0
- /package/{esm → dist/esm}/workspace/README.md +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/index.html +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/package.json +0 -0
- /package/{esm/workspace/dashboard/public/favicon.png → dist/esm/workspace/dashboard/public/favicon.ico} +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/server.js +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/src/App.jsx +0 -0
- /package/{cjs/workspace/frontend → dist/esm/workspace/dashboard}/src/main.jsx +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/vite.config.js +0 -0
- /package/{esm → dist/esm}/workspace/package.json +0 -0
- /package/{postinstall.cjs → dist/postinstall.cjs} +0 -0
- /package/{esm → src}/workspace/dashboard/src/main.jsx +0 -0
package/src/hb.js
ADDED
|
@@ -0,0 +1,967 @@
|
|
|
1
|
+
import { createSigner } from "@permaweb/aoconnect"
|
|
2
|
+
import { isEmpty, last, isNotNil, mergeLeft, clone } from "ramda"
|
|
3
|
+
import { toAddr, buildTags, seed, srcs } from "./utils.js"
|
|
4
|
+
import {
|
|
5
|
+
httpsig_from,
|
|
6
|
+
structured_to,
|
|
7
|
+
rsaid,
|
|
8
|
+
hmacid,
|
|
9
|
+
sign,
|
|
10
|
+
signer,
|
|
11
|
+
send as _send,
|
|
12
|
+
commit,
|
|
13
|
+
result,
|
|
14
|
+
} from "hbsig"
|
|
15
|
+
import hyper_aos from "./hyper-aos.js"
|
|
16
|
+
import aos_wamr from "./aos_wamr.js"
|
|
17
|
+
import { ArweaveSigner } from "@ar.io/sdk"
|
|
18
|
+
import { createData } from "@dha-team/arbundles"
|
|
19
|
+
|
|
20
|
+
// Convert objects whose keys are sequential numeric strings (e.g.
|
|
21
|
+
// `{1: "a", 2: "b"}`) into arrays. v0.9-FINAL's multipart re-encoder treats
|
|
22
|
+
// numbered TABMs as lists; JS hbsig only emits `.="list"` in ao-types when
|
|
23
|
+
// the value is an Array, so without this conversion the content-digest of
|
|
24
|
+
// the request body diverges from HB's recomputation and rsa-pss verification
|
|
25
|
+
// fails with `process_not_verified`.
|
|
26
|
+
const normalizeNumberedObjects = v => {
|
|
27
|
+
if (v === null || v === undefined) return v
|
|
28
|
+
if (Array.isArray(v)) return v.map(normalizeNumberedObjects)
|
|
29
|
+
if (Buffer.isBuffer(v) || v instanceof Blob) return v
|
|
30
|
+
if (typeof v !== "object") return v
|
|
31
|
+
const keys = Object.keys(v)
|
|
32
|
+
if (
|
|
33
|
+
keys.length > 0 &&
|
|
34
|
+
keys.every(k => /^[1-9][0-9]*$/.test(k)) &&
|
|
35
|
+
keys
|
|
36
|
+
.map(k => parseInt(k, 10))
|
|
37
|
+
.sort((a, b) => a - b)
|
|
38
|
+
.every((n, i) => n === i + 1)
|
|
39
|
+
) {
|
|
40
|
+
return keys
|
|
41
|
+
.map(k => parseInt(k, 10))
|
|
42
|
+
.sort((a, b) => a - b)
|
|
43
|
+
.map(i => normalizeNumberedObjects(v[String(i)]))
|
|
44
|
+
}
|
|
45
|
+
const out = {}
|
|
46
|
+
for (const [k, val] of Object.entries(v)) out[k] = normalizeNumberedObjects(val)
|
|
47
|
+
return out
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// v0.9-FINAL returns Messages with lowercase fields (data, target, anchor, from)
|
|
51
|
+
// where legacy AOS-format consumers expect capitalised (Data, Target, Anchor,
|
|
52
|
+
// From). Also lower-cases tag {name, value} pairs and may emit them as a
|
|
53
|
+
// numbered-key map under "tags" rather than an array under "Tags". Normalise
|
|
54
|
+
// so existing callers that read `Messages[0].Data` keep working.
|
|
55
|
+
const _normalizeLegacyResult = res => {
|
|
56
|
+
if (!res || typeof res !== "object") return res
|
|
57
|
+
const _msgs = res.Messages ?? res.messages
|
|
58
|
+
if (!Array.isArray(_msgs)) return res
|
|
59
|
+
const _tagsArray = t => {
|
|
60
|
+
if (!t) return []
|
|
61
|
+
if (Array.isArray(t)) {
|
|
62
|
+
return t.map(x => ({
|
|
63
|
+
name: x?.name ?? x?.Name,
|
|
64
|
+
value: x?.value ?? x?.Value,
|
|
65
|
+
})).filter(x => x.name != null)
|
|
66
|
+
}
|
|
67
|
+
if (typeof t === "object") {
|
|
68
|
+
return Object.keys(t)
|
|
69
|
+
.filter(k => /^\d+$/.test(k))
|
|
70
|
+
.sort((a, b) => Number(a) - Number(b))
|
|
71
|
+
.map(k => {
|
|
72
|
+
const x = t[k]
|
|
73
|
+
return {
|
|
74
|
+
name: x?.name ?? x?.Name,
|
|
75
|
+
value: x?.value ?? x?.Value,
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
.filter(x => x.name != null)
|
|
79
|
+
}
|
|
80
|
+
return []
|
|
81
|
+
}
|
|
82
|
+
const Messages = _msgs.map(m => {
|
|
83
|
+
if (!m || typeof m !== "object") return m
|
|
84
|
+
const tags = _tagsArray(m.Tags ?? m.tags)
|
|
85
|
+
return {
|
|
86
|
+
...m,
|
|
87
|
+
Data: m.Data ?? m.data,
|
|
88
|
+
Target: m.Target ?? m.target,
|
|
89
|
+
Anchor: m.Anchor ?? m.anchor,
|
|
90
|
+
From: m.From ?? m.from,
|
|
91
|
+
Tags: tags,
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
return { ...res, Messages }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const toMsg = async req => {
|
|
98
|
+
let msg = {}
|
|
99
|
+
req?.headers?.forEach((v, k) => {
|
|
100
|
+
msg[k] = v
|
|
101
|
+
})
|
|
102
|
+
//if (req.body) msg.body = await req.text?.()
|
|
103
|
+
if (req.body) {
|
|
104
|
+
const arrayBuffer = await req.arrayBuffer()
|
|
105
|
+
msg.body =
|
|
106
|
+
typeof Buffer !== "undefined"
|
|
107
|
+
? Buffer.from(arrayBuffer) // Node.js
|
|
108
|
+
: new Uint8Array(arrayBuffer) // Browser
|
|
109
|
+
}
|
|
110
|
+
return msg
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
class HB {
|
|
114
|
+
constructor({
|
|
115
|
+
url = "http://localhost:10001",
|
|
116
|
+
cu = "http://localhost:6363",
|
|
117
|
+
jwk,
|
|
118
|
+
format = "httpsig",
|
|
119
|
+
} = {}) {
|
|
120
|
+
this.format = format
|
|
121
|
+
this.cu = cu
|
|
122
|
+
this.url = url
|
|
123
|
+
if (jwk) this._init(jwk)
|
|
124
|
+
}
|
|
125
|
+
async signEncoded(encoded) {
|
|
126
|
+
const { path, ...msg } = encoded
|
|
127
|
+
return await sign({
|
|
128
|
+
jwk: this.jwk,
|
|
129
|
+
msg,
|
|
130
|
+
path,
|
|
131
|
+
url: this.url,
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
isArConnect() {
|
|
136
|
+
return this.jwk?.id || this.jwk?.walletName === "ArConnect"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
_init(jwk) {
|
|
140
|
+
this.jwk = jwk
|
|
141
|
+
this.signer = createSigner(jwk, this.url)
|
|
142
|
+
if (this.jwk && !this.isArConnect()) this.addr = toAddr(jwk.n)
|
|
143
|
+
this.sign = signer({ signer: this.signer, url: this.url })
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async setInfo() {
|
|
147
|
+
if (!this.operator) {
|
|
148
|
+
try {
|
|
149
|
+
this.operator = await this.g("/~meta@1.0/info/address")
|
|
150
|
+
} catch (e) {
|
|
151
|
+
console.log(e)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async init(jwk) {
|
|
157
|
+
this._init(jwk)
|
|
158
|
+
await this.setInfo()
|
|
159
|
+
return this
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async send(msg) {
|
|
163
|
+
return await _send(msg)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async getImage() {
|
|
167
|
+
const wasm = Buffer.from(aos_wamr, "base64")
|
|
168
|
+
const id = await this.cacheBinary(wasm, "application/wasm")
|
|
169
|
+
this.image ??= id
|
|
170
|
+
return id
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async getLua() {
|
|
174
|
+
// Decode base64 to UTF-8 text string (Lua source code)
|
|
175
|
+
const lua = Buffer.from(hyper_aos, "base64").toString("utf-8")
|
|
176
|
+
const id = await this.cacheBinary(lua, "application/lua")
|
|
177
|
+
this.lua ??= id
|
|
178
|
+
return id
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async messageAOS(args) {
|
|
182
|
+
const { slot, pid } = await this.scheduleAOS(args)
|
|
183
|
+
return { slot, outbox: await this.computeAOS({ pid, slot }) }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// JS-side push for AOS (wasm-64/stack@1.0) processes.
|
|
187
|
+
// The HyperBEAM push@1.0 device has a bug where subresolve's deep-merge
|
|
188
|
+
// modifies the process key, causing a ProcID mismatch and cache miss.
|
|
189
|
+
// This method implements the same logic using direct HTTP calls that work.
|
|
190
|
+
// Handles full cross-process round-trips: A→B→A for receive() resolution.
|
|
191
|
+
async pushAOS({ pid, slot, outbox: initialOutbox, maxDepth = 10 }) {
|
|
192
|
+
let currentSlot = Number(slot)
|
|
193
|
+
let lastOutbox = null
|
|
194
|
+
|
|
195
|
+
for (let depth = 0; depth < maxDepth; depth++) {
|
|
196
|
+
let outbox
|
|
197
|
+
if (depth === 0 && initialOutbox && typeof initialOutbox === "object") {
|
|
198
|
+
outbox = initialOutbox
|
|
199
|
+
} else {
|
|
200
|
+
try {
|
|
201
|
+
outbox = await this.computeAOS({ pid, slot: currentSlot })
|
|
202
|
+
} catch (_e) {
|
|
203
|
+
break
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
lastOutbox = outbox
|
|
207
|
+
if (!outbox || typeof outbox !== "object") break
|
|
208
|
+
|
|
209
|
+
const msgs = this._extractOutboxMsgs(outbox)
|
|
210
|
+
if (msgs.length === 0) break
|
|
211
|
+
|
|
212
|
+
let hasSelfMsg = false
|
|
213
|
+
let nextSlot = currentSlot
|
|
214
|
+
|
|
215
|
+
for (const msg of msgs) {
|
|
216
|
+
const target = msg.target ?? msg.Target
|
|
217
|
+
if (!target) continue
|
|
218
|
+
|
|
219
|
+
const tags = {}
|
|
220
|
+
for (const [key, val] of Object.entries(msg)) {
|
|
221
|
+
const lk = key.toLowerCase()
|
|
222
|
+
if (lk === "data" || lk === "target" || lk === "anchor") continue
|
|
223
|
+
if (typeof val === "string" || typeof val === "number") {
|
|
224
|
+
tags[key] = String(val)
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
tags["from-process"] = pid
|
|
228
|
+
|
|
229
|
+
const data = msg.data ?? msg.Data ?? ""
|
|
230
|
+
const action = tags.Action ?? tags.action ?? null
|
|
231
|
+
delete tags.Action
|
|
232
|
+
delete tags.action
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
const { slot: newSlot } = await this.scheduleAOS({
|
|
236
|
+
pid: target,
|
|
237
|
+
action,
|
|
238
|
+
data,
|
|
239
|
+
tags,
|
|
240
|
+
})
|
|
241
|
+
if (target === pid) {
|
|
242
|
+
nextSlot = Math.max(nextSlot, Number(newSlot))
|
|
243
|
+
hasSelfMsg = true
|
|
244
|
+
} else {
|
|
245
|
+
// Cross-process: compute target, deliver any replies back to pid
|
|
246
|
+
try {
|
|
247
|
+
const targetOutbox = await this.computeAOS({
|
|
248
|
+
pid: target,
|
|
249
|
+
slot: newSlot,
|
|
250
|
+
})
|
|
251
|
+
if (targetOutbox && typeof targetOutbox === "object") {
|
|
252
|
+
const replies = this._extractOutboxMsgs(targetOutbox)
|
|
253
|
+
for (const reply of replies) {
|
|
254
|
+
const replyTarget = reply.target ?? reply.Target
|
|
255
|
+
if (!replyTarget) continue
|
|
256
|
+
const rTags = {}
|
|
257
|
+
for (const [rk, rv] of Object.entries(reply)) {
|
|
258
|
+
const rl = rk.toLowerCase()
|
|
259
|
+
if (rl === "data" || rl === "target" || rl === "anchor")
|
|
260
|
+
continue
|
|
261
|
+
if (typeof rv === "string" || typeof rv === "number") {
|
|
262
|
+
rTags[rk] = String(rv)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
rTags["from-process"] = target
|
|
266
|
+
const rData = reply.data ?? reply.Data ?? ""
|
|
267
|
+
const rAction = rTags.Action ?? rTags.action ?? null
|
|
268
|
+
delete rTags.Action
|
|
269
|
+
delete rTags.action
|
|
270
|
+
try {
|
|
271
|
+
const { slot: replySlot } = await this.scheduleAOS({
|
|
272
|
+
pid: replyTarget,
|
|
273
|
+
action: rAction,
|
|
274
|
+
data: rData,
|
|
275
|
+
tags: rTags,
|
|
276
|
+
})
|
|
277
|
+
if (replyTarget === pid) {
|
|
278
|
+
nextSlot = Math.max(nextSlot, Number(replySlot))
|
|
279
|
+
hasSelfMsg = true
|
|
280
|
+
}
|
|
281
|
+
} catch (_e) {}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
} catch (_e) {}
|
|
285
|
+
}
|
|
286
|
+
} catch (_e) {}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (!hasSelfMsg) break
|
|
290
|
+
currentSlot = nextSlot
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return { slot: currentSlot, outbox: lastOutbox }
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Extract outbox messages from a compute result (numbered keys).
|
|
297
|
+
_extractOutboxMsgs(outbox) {
|
|
298
|
+
return Object.keys(outbox)
|
|
299
|
+
.filter(k => /^\d+$/.test(k))
|
|
300
|
+
.sort((a, b) => Number(a) - Number(b))
|
|
301
|
+
.map(k => outbox[k])
|
|
302
|
+
.filter(m => m && typeof m === "object")
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async messageLegacy(args) {
|
|
306
|
+
const { slot, pid } = await this.scheduleLegacy(args)
|
|
307
|
+
return { slot, res: await this.computeLegacy({ pid, slot }) }
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async computeAOS({ pid, slot }) {
|
|
311
|
+
return await this.getJSON({ path: `/${pid}/compute/results/outbox`, slot })
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async computeLua({ pid, slot }) {
|
|
315
|
+
return await this.getJSON({ path: `/${pid}/compute/results`, slot })
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async compute({ pid, slot, path = "" }) {
|
|
319
|
+
if (path && !/^\//.test(path)) path = "/" + path
|
|
320
|
+
if (this.format === "ans104") {
|
|
321
|
+
const res = await this.get({ path: `/${pid}/compute${path}`, slot })
|
|
322
|
+
return res.out
|
|
323
|
+
} else {
|
|
324
|
+
return await this.getJSON({ path: `/${pid}/compute${path}`, slot })
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async computeLegacy({ pid, slot }) {
|
|
329
|
+
// Match master: compute and parse results.json.body
|
|
330
|
+
const json = await this.compute({ pid, slot })
|
|
331
|
+
let parsed = json
|
|
332
|
+
if (json?.results?.json?.body) {
|
|
333
|
+
parsed = JSON.parse(json.results.json.body)
|
|
334
|
+
} else if (json?.["compute/results/json"]?.body) {
|
|
335
|
+
parsed = JSON.parse(json["compute/results/json"].body)
|
|
336
|
+
} else if (json?.results?.raw) {
|
|
337
|
+
const raw = typeof json.results.raw === "string"
|
|
338
|
+
? JSON.parse(json.results.raw) : json.results.raw
|
|
339
|
+
if (raw?.Messages || raw?.Output) parsed = raw
|
|
340
|
+
}
|
|
341
|
+
return _normalizeLegacyResult(parsed)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
async cacheScript(data, type = "application/lua") {
|
|
345
|
+
if (!this.cache) {
|
|
346
|
+
const { pid } = await this.spawn({})
|
|
347
|
+
this.cache = pid
|
|
348
|
+
}
|
|
349
|
+
const { slot } = await this.schedule({
|
|
350
|
+
data,
|
|
351
|
+
pid: this.cache,
|
|
352
|
+
tags: { "content-type": type },
|
|
353
|
+
})
|
|
354
|
+
const msgs = await this.messages({ pid: this.cache, from: slot, limit: 1 })
|
|
355
|
+
return msgs.edges[0].node.message.Id
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async cacheBinary(data, type) {
|
|
359
|
+
// Convert Buffer to base64 string to avoid signature mismatch in JSON POST.
|
|
360
|
+
// Buffer goes through structured field byte encoding in commit (`:base64:`)
|
|
361
|
+
// but jsonReplacer converts to plain base64 string, causing invalid_commitment.
|
|
362
|
+
const dataStr = Buffer.isBuffer(data) ? data.toString("base64") : data
|
|
363
|
+
const res = await this.post({
|
|
364
|
+
path: "/~wao@1.0/cache_module",
|
|
365
|
+
data: dataStr,
|
|
366
|
+
type,
|
|
367
|
+
})
|
|
368
|
+
return res.out.id
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
async message(args) {
|
|
372
|
+
const pid = args.pid
|
|
373
|
+
const { slot } = await this.schedule(args)
|
|
374
|
+
const res = await this.compute({ pid, slot })
|
|
375
|
+
return { slot, pid, res }
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async scheduleFlat({ pid, tags = {}, data } = {}) {
|
|
379
|
+
let _tags = mergeLeft(tags, { Type: "Message", target: pid })
|
|
380
|
+
if (data) _tags.data = data
|
|
381
|
+
let res = await this.post({ path: "/~process@1.0/schedule", body: _tags })
|
|
382
|
+
return { slot: res.out.slot, res, pid }
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
async scheduleNP({ pid, tags = {}, data } = {}) {
|
|
386
|
+
if (data) tags.data = data
|
|
387
|
+
// Use direct fetch to avoid post() path conflation.
|
|
388
|
+
// Commit tags without mixing in the request path.
|
|
389
|
+
tags.nonce ??= seed(8)
|
|
390
|
+
const committed = await this.commit(tags, { path: false })
|
|
391
|
+
const requestPath = `/${pid}~node-process@1.0/schedule`
|
|
392
|
+
const response = await fetch(`${this.url}${requestPath}`, {
|
|
393
|
+
method: "POST",
|
|
394
|
+
headers: { "content-type": "application/json", "accept-bundle": "true" },
|
|
395
|
+
body: JSON.stringify(committed),
|
|
396
|
+
})
|
|
397
|
+
if (response.status >= 400) {
|
|
398
|
+
const text = await response.text()
|
|
399
|
+
throw new Error(`${response.status}: ${text}`)
|
|
400
|
+
}
|
|
401
|
+
const res = await result(response)
|
|
402
|
+
return { slot: res.out?.slot, res, pid }
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
async send104({ path = "/~process@1.0/schedule", item }) {
|
|
406
|
+
let res = await fetch(`${this.url}${path}`, {
|
|
407
|
+
method: "POST",
|
|
408
|
+
headers: {
|
|
409
|
+
"codec-device": "ans104@1.0",
|
|
410
|
+
"Content-Type": "application/ans104",
|
|
411
|
+
},
|
|
412
|
+
body: item.binary,
|
|
413
|
+
})
|
|
414
|
+
return await result(res)
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
async post104({
|
|
418
|
+
path = "/~process@1.0/schedule",
|
|
419
|
+
tags = {},
|
|
420
|
+
data = "1984",
|
|
421
|
+
target,
|
|
422
|
+
}) {
|
|
423
|
+
const _tags = buildTags(mergeLeft(tags, { signingFormat: "ANS-104" }))
|
|
424
|
+
const signer = new ArweaveSigner(this.jwk)
|
|
425
|
+
const item = createData(data, signer, { tags: _tags, target })
|
|
426
|
+
await item.sign(signer)
|
|
427
|
+
return await this.send104({ path, item })
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async schedule({ pid, tags = {}, data } = {}) {
|
|
431
|
+
let res = null
|
|
432
|
+
if (this.format === "ans104") {
|
|
433
|
+
let _tags = mergeLeft(tags, { Type: "Message" })
|
|
434
|
+
res = await this.post104({
|
|
435
|
+
target: pid,
|
|
436
|
+
path: `/${pid}/schedule`,
|
|
437
|
+
tags: _tags,
|
|
438
|
+
data: data ?? "1984",
|
|
439
|
+
})
|
|
440
|
+
return { slot: res.out.slot, res, pid }
|
|
441
|
+
} else {
|
|
442
|
+
let _tags = mergeLeft(tags, { Type: "Message", target: pid })
|
|
443
|
+
if (data) _tags.data = data
|
|
444
|
+
|
|
445
|
+
const res = await this.post({
|
|
446
|
+
path: "/~scheduler@1.0/schedule",
|
|
447
|
+
..._tags,
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
const slot = parseInt(res.headers?.slot ?? res.out?.slot)
|
|
451
|
+
return {
|
|
452
|
+
slot,
|
|
453
|
+
pid,
|
|
454
|
+
res: { status: res.status },
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async scheduleLua({ action = "Eval", tags = {}, ...rest }) {
|
|
460
|
+
if (action) tags.Action = action
|
|
461
|
+
return await this.schedule({ tags, ...rest })
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
async spawnLua(lua) {
|
|
465
|
+
await this.setInfo()
|
|
466
|
+
// Try local wao@1.0 cache first, fall back to Arweave TX ID for remote
|
|
467
|
+
let module = this.lua
|
|
468
|
+
if (!module) {
|
|
469
|
+
try {
|
|
470
|
+
module = await this.getLua()
|
|
471
|
+
} catch (_e) {
|
|
472
|
+
module = srcs.module_lua
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const tags = {
|
|
476
|
+
"data-protocol": "ao",
|
|
477
|
+
variant: "ao.TN.1",
|
|
478
|
+
module,
|
|
479
|
+
"execution-device": "lua@5.3a",
|
|
480
|
+
"push-device": "push@1.0",
|
|
481
|
+
"patch-from": "/results/outbox",
|
|
482
|
+
// Note: 'authority' excluded - conflicts with HTTP Message Signatures '@authority'
|
|
483
|
+
// The Lua boot module (hyper-aos.js) is patched to default ao.authorities to {}
|
|
484
|
+
}
|
|
485
|
+
return this.spawn(tags)
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
async now({ pid, path = "" }) {
|
|
489
|
+
if (path && !/^\//.test(path)) path = "/" + path
|
|
490
|
+
if (this.format === "ans104") {
|
|
491
|
+
const res = await this.get({ path: `/${pid}/now${path}` })
|
|
492
|
+
return res.out
|
|
493
|
+
} else {
|
|
494
|
+
return await this.getJSON({ path: `/${pid}/now${path}` })
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
async slot({ pid, path = "" }) {
|
|
499
|
+
if (path && !/^\//.test(path)) path = "/" + path
|
|
500
|
+
return await this.getJSON({ path: `/${pid}/slot${path}` })
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
async messages({ pid, from, to } = {}) {
|
|
504
|
+
let params = `target=${pid}`
|
|
505
|
+
if (isNotNil(from)) params += `&from=${from}`
|
|
506
|
+
if (isNotNil(to)) params += `&to=${to}`
|
|
507
|
+
params += `&accept=application/aos-2`
|
|
508
|
+
let res = await fetch(`${this.url}/~scheduler@1.0/schedule?${params}`).then(
|
|
509
|
+
r => r.json()
|
|
510
|
+
)
|
|
511
|
+
if (res.page_info.has_next_page) {
|
|
512
|
+
res.next = async () => {
|
|
513
|
+
const from2 = last(res.edges).cursor + 1
|
|
514
|
+
return await this.messages({ pid, from: from2, to })
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return res
|
|
518
|
+
}
|
|
519
|
+
async spawn(tags = {}) {
|
|
520
|
+
await this.setInfo()
|
|
521
|
+
// v0.9-FINAL multipart re-encoding sees a numbered-key object as a list
|
|
522
|
+
// (TABM with .="list" in ao-types). JS hbsig's structured codec encodes
|
|
523
|
+
// a plain numeric-keyed object without that marker, so HB's recomputed
|
|
524
|
+
// content-digest doesn't match what JS signed and verify fails. Pre-
|
|
525
|
+
// normalize any numbered-key object value into an array so the array
|
|
526
|
+
// path (which already emits .="list") is used.
|
|
527
|
+
tags = normalizeNumberedObjects(tags)
|
|
528
|
+
let res = null
|
|
529
|
+
if (this.format === "ans104") {
|
|
530
|
+
res = await this.post104({
|
|
531
|
+
tags: mergeLeft(tags, {
|
|
532
|
+
"codec-device": "ans104@1.0",
|
|
533
|
+
"random-seed": seed(16),
|
|
534
|
+
Type: "Process",
|
|
535
|
+
"execution-device": "test-device@1.0",
|
|
536
|
+
device: "process@1.0",
|
|
537
|
+
Scheduler: this.operator,
|
|
538
|
+
}),
|
|
539
|
+
})
|
|
540
|
+
return { res, pid: res.out.process }
|
|
541
|
+
} else {
|
|
542
|
+
// Use httpsig-signed multipart POST
|
|
543
|
+
const spawnTags = mergeLeft(tags, {
|
|
544
|
+
"random-seed": seed(16),
|
|
545
|
+
type: "Process",
|
|
546
|
+
"execution-device": "test-device@1.0",
|
|
547
|
+
device: "process@1.0",
|
|
548
|
+
scheduler: this.operator ?? this.addr,
|
|
549
|
+
})
|
|
550
|
+
|
|
551
|
+
const res = await this.post({
|
|
552
|
+
path: "/~scheduler@1.0/schedule",
|
|
553
|
+
...spawnTags,
|
|
554
|
+
})
|
|
555
|
+
|
|
556
|
+
return {
|
|
557
|
+
pid: res.headers?.process || res.out?.process,
|
|
558
|
+
slot: parseInt(res.headers?.slot ?? res.out?.slot),
|
|
559
|
+
res: { status: res.status },
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async spawnLegacy({ module, tags = {}, data } = {}) {
|
|
565
|
+
await this.setInfo()
|
|
566
|
+
// Use ANS-104 format to include 'authority' and 'push-device' tags.
|
|
567
|
+
// httpsig format can't include 'authority' — it conflicts with HTTP Signatures'
|
|
568
|
+
// @authority derived component (RFC 9421), causing signature verification failure.
|
|
569
|
+
const legacyTags = {
|
|
570
|
+
"Data-Protocol": "ao",
|
|
571
|
+
Variant: "ao.TN.1",
|
|
572
|
+
Scheduler: this.operator ?? this.addr,
|
|
573
|
+
Module: module ?? "ISShJH1ij-hPPt9St5UFFr_8Ys3Kj5cyg7zrMGt7H9s",
|
|
574
|
+
device: "process@1.0",
|
|
575
|
+
"execution-device": "genesis-wasm@1.0",
|
|
576
|
+
"push-device": "push@1.0",
|
|
577
|
+
authority: this.addr,
|
|
578
|
+
"random-seed": seed(16),
|
|
579
|
+
Type: "Process",
|
|
580
|
+
}
|
|
581
|
+
const t = mergeLeft(tags, legacyTags)
|
|
582
|
+
|
|
583
|
+
// Prepend self-trust + authority management to boot data.
|
|
584
|
+
// Push device re-schedules outbox messages with from-process = process_id.
|
|
585
|
+
// AOS getOwner() returns from-process when present, so trust is based on the
|
|
586
|
+
// sender's process ID, not the signer. We add ao.id for self-trust and provide
|
|
587
|
+
// an AddAuthority handler for cross-process trust.
|
|
588
|
+
let bootData = data ?? "1984"
|
|
589
|
+
if (t["On-Boot"] === "Data" && typeof bootData === "string") {
|
|
590
|
+
const trustPreamble = [
|
|
591
|
+
"table.insert(ao.authorities, ao.id)",
|
|
592
|
+
'Handlers.add("__AddAuthority", "__AddAuthority", function(msg)',
|
|
593
|
+
" table.insert(ao.authorities, msg.Addr)",
|
|
594
|
+
' msg.reply({ Data = "ok" })',
|
|
595
|
+
"end)",
|
|
596
|
+
].join("\n")
|
|
597
|
+
bootData = trustPreamble + "\n" + bootData
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const res = await this.post104({
|
|
601
|
+
path: "/~scheduler@1.0/schedule",
|
|
602
|
+
tags: t,
|
|
603
|
+
data: bootData,
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
return {
|
|
607
|
+
pid: res.out?.process,
|
|
608
|
+
slot: parseInt(res.out?.slot ?? "0"),
|
|
609
|
+
res: { status: 200 },
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
async scheduleLegacy({ action = "Eval", tags = {}, ...rest } = {}) {
|
|
614
|
+
// Use uppercase 'Action' to match AOS handler matching (msg.Action)
|
|
615
|
+
if (action) tags.Action = action
|
|
616
|
+
return await this.schedule({ tags, ...rest })
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
async results({ process, limit, sort = "DESC", from, to } = {}) {
|
|
620
|
+
let params = ""
|
|
621
|
+
const addParam = (key, val) => {
|
|
622
|
+
params += params === "" ? "?" : "&"
|
|
623
|
+
params += `${key}=${val}`
|
|
624
|
+
}
|
|
625
|
+
if (limit) addParam("limit", limit)
|
|
626
|
+
if (sort) addParam("sort", sort)
|
|
627
|
+
if (from) addParam("from", from)
|
|
628
|
+
if (to) addParam("to", to)
|
|
629
|
+
const res = await this.post({
|
|
630
|
+
path: "/~relay@1.0/call",
|
|
631
|
+
method: "GET",
|
|
632
|
+
"relay-path": `${this.cu}/results/${process}${params}`,
|
|
633
|
+
"Content-Type": "application/json",
|
|
634
|
+
})
|
|
635
|
+
return JSON.parse(res.body)
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
async dryrun({ tags = {}, pid, action, data } = {}) {
|
|
639
|
+
if (typeof action === "string") tags.Action = action
|
|
640
|
+
let json = { Tags: buildTags({ ...tags }), Owner: this.addr }
|
|
641
|
+
if (data) json.Data = data
|
|
642
|
+
const res = await this.post({
|
|
643
|
+
path: "/~relay@1.0/call",
|
|
644
|
+
method: "POST",
|
|
645
|
+
"relay-path": `${this.cu}/dry-run?process-id=${pid}`,
|
|
646
|
+
"Content-Type": "application/json",
|
|
647
|
+
"relay-body": JSON.stringify(json),
|
|
648
|
+
})
|
|
649
|
+
return JSON.parse(res.body)
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
async commit(obj, opts) {
|
|
653
|
+
return await commit(obj, { ...opts, signer: this.sign })
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
async p(path, ...args) {
|
|
657
|
+
let _args = clone(args)
|
|
658
|
+
_args[0] ??= {}
|
|
659
|
+
_args[0].path ??= path
|
|
660
|
+
return (await this.post(..._args))?.out ?? null
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
async post(obj, opt = {}) {
|
|
664
|
+
const _json = opt.json ? "/~json@1.0/serialize" : ""
|
|
665
|
+
obj.path += _json
|
|
666
|
+
// Flatten nested 'body' object to top-level fields.
|
|
667
|
+
// Old API used body: { key: value } for multipart POST; now these
|
|
668
|
+
// fields must be at the top level for the signing pipeline.
|
|
669
|
+
if (obj.body && typeof obj.body === "object" && !Buffer.isBuffer(obj.body)
|
|
670
|
+
&& !(obj.body instanceof Blob) && !Array.isArray(obj.body)) {
|
|
671
|
+
const originalPath = obj.path
|
|
672
|
+
const { body, ...rest } = obj
|
|
673
|
+
obj = { ...rest, ...body }
|
|
674
|
+
if (originalPath) obj.path = originalPath
|
|
675
|
+
}
|
|
676
|
+
if (Buffer.isBuffer(obj.body)) {
|
|
677
|
+
obj.body = obj.body.toString()
|
|
678
|
+
}
|
|
679
|
+
if (obj["ao-body-key"] === "body") {
|
|
680
|
+
delete obj["ao-body-key"]
|
|
681
|
+
}
|
|
682
|
+
obj.nonce ??= seed(8)
|
|
683
|
+
|
|
684
|
+
// Check if message has nested objects/arrays (excluding metadata fields).
|
|
685
|
+
// Nested values require multipart encoding for the signer to properly
|
|
686
|
+
// handle them. JSON POST can't preserve nested structures through the
|
|
687
|
+
// signing→verification round-trip because the structured codec changes
|
|
688
|
+
// the value representation (linkification) before verification.
|
|
689
|
+
const hasNested = Object.entries(obj).some(([key, value]) => {
|
|
690
|
+
if (key === "path" || key === "body" || key === "commitments" || key === "ao-types") return false
|
|
691
|
+
if (Array.isArray(value)) return true
|
|
692
|
+
if (typeof value === "object" && value !== null
|
|
693
|
+
&& !Buffer.isBuffer(value) && !(value instanceof Blob)) return true
|
|
694
|
+
return false
|
|
695
|
+
})
|
|
696
|
+
|
|
697
|
+
if (hasNested) {
|
|
698
|
+
// Direct HTTPSig multipart POST for messages with nested objects.
|
|
699
|
+
const signedMsg = await this.sign(obj)
|
|
700
|
+
let response
|
|
701
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
702
|
+
try {
|
|
703
|
+
response = await fetch(signedMsg.url, {
|
|
704
|
+
method: signedMsg.method || "POST",
|
|
705
|
+
headers: signedMsg.headers,
|
|
706
|
+
body: signedMsg.body,
|
|
707
|
+
})
|
|
708
|
+
break
|
|
709
|
+
} catch (e) {
|
|
710
|
+
if (attempt === 2) throw e
|
|
711
|
+
await new Promise(r => setTimeout(r, 1000 * (attempt + 1)))
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
if (response.status >= 400) {
|
|
715
|
+
const text = await response.text()
|
|
716
|
+
throw new Error(`${response.status}: ${text}`)
|
|
717
|
+
}
|
|
718
|
+
return await result(response)
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// JSON POST with commitment signatures for flat messages.
|
|
722
|
+
// path: false because @path derived component causes mismatch when
|
|
723
|
+
// HyperBEAM reconstructs signature base from committed field "path"
|
|
724
|
+
const committed = await this.commit(obj, { path: false })
|
|
725
|
+
const jsonReplacer = (key, value) => {
|
|
726
|
+
if (value?.type === "Buffer" && Array.isArray(value?.data)) {
|
|
727
|
+
return Buffer.from(value.data).toString("base64")
|
|
728
|
+
}
|
|
729
|
+
if (Buffer.isBuffer(value)) {
|
|
730
|
+
return value.toString("base64")
|
|
731
|
+
}
|
|
732
|
+
return value
|
|
733
|
+
}
|
|
734
|
+
const jsonBody = JSON.stringify(committed, jsonReplacer)
|
|
735
|
+
const fetchUrl = `${this.url}${obj.path}`
|
|
736
|
+
const fetchOpts = {
|
|
737
|
+
method: "POST",
|
|
738
|
+
headers: { "content-type": "application/json", "accept-bundle": "true" },
|
|
739
|
+
body: jsonBody,
|
|
740
|
+
}
|
|
741
|
+
let response
|
|
742
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
743
|
+
try {
|
|
744
|
+
response = await fetch(fetchUrl, fetchOpts)
|
|
745
|
+
break
|
|
746
|
+
} catch (e) {
|
|
747
|
+
if (attempt === 2) throw e
|
|
748
|
+
await new Promise(r => setTimeout(r, 1000 * (attempt + 1)))
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (response.status >= 400) {
|
|
752
|
+
const text = await response.text()
|
|
753
|
+
throw new Error(`${response.status}: ${text}`)
|
|
754
|
+
}
|
|
755
|
+
return await result(response)
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// Decode base64-encoded multipart body from HyperBEAM responses.
|
|
759
|
+
// When HyperBEAM returns cached/stored messages, the body may be
|
|
760
|
+
// base64-encoded multipart form-data. This method decodes it and
|
|
761
|
+
// extracts parts based on the ao-result header.
|
|
762
|
+
_decodeResult(res) {
|
|
763
|
+
if (!res.body || typeof res.body !== "string") return res
|
|
764
|
+
const aoResult = res.headers?.["ao-result"]
|
|
765
|
+
|
|
766
|
+
// Try to detect and decode base64-encoded multipart body
|
|
767
|
+
try {
|
|
768
|
+
const decoded = Buffer.from(res.body, "base64").toString("binary")
|
|
769
|
+
if (decoded.startsWith("--") && decoded.includes("content-disposition")) {
|
|
770
|
+
// It's multipart form-data encoded as base64
|
|
771
|
+
res.body = decoded
|
|
772
|
+
|
|
773
|
+
if (aoResult) {
|
|
774
|
+
// Extract the named part from multipart
|
|
775
|
+
const boundaryMatch = decoded.match(/^--([^\r\n]+)/)
|
|
776
|
+
if (boundaryMatch) {
|
|
777
|
+
const boundary = boundaryMatch[1]
|
|
778
|
+
const parts = decoded.split(`--${boundary}`)
|
|
779
|
+
for (const part of parts) {
|
|
780
|
+
if (!part || part.startsWith("--")) continue
|
|
781
|
+
const nameMatch = part.match(/name="([^"]+)"/)
|
|
782
|
+
if (nameMatch && nameMatch[1] === aoResult) {
|
|
783
|
+
const sepIdx = part.indexOf("\r\n\r\n")
|
|
784
|
+
if (sepIdx !== -1) {
|
|
785
|
+
let content = part.substring(sepIdx + 4)
|
|
786
|
+
// Remove trailing CRLF
|
|
787
|
+
content = content.replace(/\r\n$/, "")
|
|
788
|
+
res.out = content
|
|
789
|
+
}
|
|
790
|
+
break
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
} catch (e) {
|
|
797
|
+
// Not valid base64 or not multipart - use as-is
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
return res
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
async g(path, ...args) {
|
|
804
|
+
let _args = clone(args)
|
|
805
|
+
_args[0] ??= {}
|
|
806
|
+
_args[0].path ??= path
|
|
807
|
+
return (await this.get(..._args))?.out ?? null
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
async get({ path, ...params }, opt = {}) {
|
|
811
|
+
const _json = opt.json ? "/~json@1.0/serialize" : ""
|
|
812
|
+
path ??= "/~message@1.0"
|
|
813
|
+
if (!/^\//.test(path)) path = "/" + path
|
|
814
|
+
let _params = ""
|
|
815
|
+
if (!isEmpty(params)) {
|
|
816
|
+
let i = 0
|
|
817
|
+
for (const k in params) {
|
|
818
|
+
_params += `${i === 0 ? "?" : "&"}${k}=${params[k]}`
|
|
819
|
+
i++
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
// Add accept-bundle header to get inline data instead of links
|
|
823
|
+
const url = `${this.url}${path}${_json}${_params}`
|
|
824
|
+
let response
|
|
825
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
826
|
+
try {
|
|
827
|
+
response = await fetch(url, { headers: { "accept-bundle": "true" } })
|
|
828
|
+
break
|
|
829
|
+
} catch (e) {
|
|
830
|
+
if (attempt === 2) throw e
|
|
831
|
+
await new Promise(r => setTimeout(r, 1000 * (attempt + 1)))
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return this._decodeResult(await result(response))
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
async postJSON(args, opt = {}) {
|
|
838
|
+
const res = await this.post(args, { ...opt, json: true })
|
|
839
|
+
return JSON.parse(res.body)
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
async getJSON(args, opt = {}) {
|
|
843
|
+
// Use regular GET with structured output instead of json@1.0/serialize
|
|
844
|
+
// because the JSON serializer doesn't resolve linkified fields (body+link)
|
|
845
|
+
const res = await this.get(args, opt)
|
|
846
|
+
return res.out
|
|
847
|
+
}
|
|
848
|
+
async spawnAOS({ image, module, sign } = {}) {
|
|
849
|
+
await this.setInfo()
|
|
850
|
+
const isLocal =
|
|
851
|
+
sign === "httpsig" ? true
|
|
852
|
+
: sign === "ans104" ? false
|
|
853
|
+
: this.url.includes("localhost") || this.url.includes("127.0.0.1")
|
|
854
|
+
|
|
855
|
+
// Default: use Arweave WASI WASM module (works on all nodes)
|
|
856
|
+
// Local: wao@1.0 cache with bundled binary (faster, no network fetch)
|
|
857
|
+
if (!image && !this.image) {
|
|
858
|
+
module ??= srcs.module_wasi
|
|
859
|
+
try {
|
|
860
|
+
// Try local wao@1.0 cache first (fast path for local HB)
|
|
861
|
+
await this.getImage()
|
|
862
|
+
} catch (_e) {
|
|
863
|
+
// Use Arweave TX ID directly — node resolves via hb_store_gateway
|
|
864
|
+
image = module
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
image ??= this.image
|
|
868
|
+
|
|
869
|
+
const baseTags = {
|
|
870
|
+
"data-protocol": "ao",
|
|
871
|
+
variant: "ao.TN.1",
|
|
872
|
+
image,
|
|
873
|
+
"execution-device": "stack@1.0",
|
|
874
|
+
"push-device": "push@1.0",
|
|
875
|
+
"output-prefix": "wasm",
|
|
876
|
+
"patch-from": "/results/outbox",
|
|
877
|
+
"patch-mode": "patches",
|
|
878
|
+
passes: 2,
|
|
879
|
+
"random-seed": seed(16),
|
|
880
|
+
type: "Process",
|
|
881
|
+
device: "process@1.0",
|
|
882
|
+
scheduler: this.operator ?? this.addr,
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
let res
|
|
886
|
+
if (isLocal) {
|
|
887
|
+
// Local: Use httpsig encoding so device-stack is committed as a typed
|
|
888
|
+
// list. ANS-104 encodes device-stack as flat device-stack/N tags which
|
|
889
|
+
// get aggregated into an uncommitted map by structured@1.0, then stripped
|
|
890
|
+
// by with_only_committed during cache write/read — breaking second compute
|
|
891
|
+
// with {error, no_valid_device_stack}. httpsig signature covers HTTP
|
|
892
|
+
// header string values; ao-types transforms happen before verification
|
|
893
|
+
// with re-encoding for checking, so the committed list survives cache.
|
|
894
|
+
// Note: 'authority' excluded — conflicts with HTTP Signatures '@authority'
|
|
895
|
+
// derived component (RFC 9421). Self-trust is injected via Lua eval below.
|
|
896
|
+
res = await this.post({
|
|
897
|
+
path: "/~scheduler@1.0/schedule",
|
|
898
|
+
...baseTags,
|
|
899
|
+
"device-stack": [
|
|
900
|
+
"wasi@1.0",
|
|
901
|
+
"json-iface@1.0",
|
|
902
|
+
"wasm-64@1.0",
|
|
903
|
+
"patch@1.0",
|
|
904
|
+
"multipass@1.0",
|
|
905
|
+
],
|
|
906
|
+
})
|
|
907
|
+
} else {
|
|
908
|
+
// Remote: Use ANS-104 because push.forward.computer nodes don't accept
|
|
909
|
+
// httpsig multipart. ANS-104 flat tags are fine for push-only nodes
|
|
910
|
+
// (no compute, so no cache round-trip stripping issue).
|
|
911
|
+
const tags = { ...baseTags, authority: this.addr }
|
|
912
|
+
tags["device-stack/1"] = "wasi@1.0"
|
|
913
|
+
tags["device-stack/2"] = "json-iface@1.0"
|
|
914
|
+
tags["device-stack/3"] = "wasm-64@1.0"
|
|
915
|
+
tags["device-stack/4"] = "patch@1.0"
|
|
916
|
+
tags["device-stack/5"] = "multipass@1.0"
|
|
917
|
+
tags["ao-types"] = 'passes="integer"'
|
|
918
|
+
res = await this.post104({
|
|
919
|
+
path: "/~scheduler@1.0/schedule",
|
|
920
|
+
tags,
|
|
921
|
+
})
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
const pid = res.headers?.process || res.out?.process
|
|
925
|
+
|
|
926
|
+
if (isLocal) {
|
|
927
|
+
// Compute slot 0 (the spawn itself) to initialize the process in the
|
|
928
|
+
// scheduler registry. Without this, immediate scheduleAOS calls fail
|
|
929
|
+
// with process_not_available because the scheduler hasn't processed
|
|
930
|
+
// the spawn yet.
|
|
931
|
+
try {
|
|
932
|
+
await this.computeAOS({ pid, slot: 0 })
|
|
933
|
+
} catch (_e) {}
|
|
934
|
+
|
|
935
|
+
// Schedule self-trust eval so push-delivered messages from this process
|
|
936
|
+
// are accepted. The 'authority' tag can't be used in httpsig spawn
|
|
937
|
+
// (conflicts with HTTP Signatures @authority), so inject via Lua eval.
|
|
938
|
+
try {
|
|
939
|
+
await this.scheduleAOS({
|
|
940
|
+
pid,
|
|
941
|
+
action: "Eval",
|
|
942
|
+
data: [
|
|
943
|
+
"table.insert(ao.authorities, ao.id)",
|
|
944
|
+
'Handlers.add("__AddAuthority", "__AddAuthority", function(msg)',
|
|
945
|
+
" table.insert(ao.authorities, msg.Addr)",
|
|
946
|
+
' msg.reply({ Data = "ok" })',
|
|
947
|
+
"end)",
|
|
948
|
+
].join("\n"),
|
|
949
|
+
tags: {},
|
|
950
|
+
})
|
|
951
|
+
} catch (_e) {}
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
return {
|
|
955
|
+
pid,
|
|
956
|
+
slot: parseInt(res.headers?.slot ?? res.out?.slot),
|
|
957
|
+
res: { status: res.status },
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
async scheduleAOS({ action = "Eval", tags = {}, ...rest }) {
|
|
962
|
+
if (action) tags.Action = action
|
|
963
|
+
return await this.schedule({ tags, ...rest })
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
export default HB
|