├── .node-version ├── .prettierignore ├── packages ├── lib-sqlite │ ├── README.md │ ├── src │ │ ├── utils │ │ │ └── identity.ts │ │ ├── types │ │ │ ├── sqlite-datatypes.ts │ │ │ ├── migration.ts │ │ │ └── simplified-database.ts │ │ ├── index.ts │ │ └── define-table.ts │ ├── test │ │ └── utils │ │ │ ├── dump-table.ts │ │ │ └── create-test-database.ts │ └── tsconfig.json ├── lib-http-server │ ├── README.md │ ├── src │ │ ├── constants.ts │ │ ├── types │ │ │ ├── environment.d.ts │ │ │ ├── http-response.ts │ │ │ ├── http-result.ts │ │ │ ├── http-failure.ts │ │ │ └── context.ts │ │ ├── utils │ │ │ ├── normalize-path.ts │ │ │ ├── is-dynamic-path.ts │ │ │ └── get-response-from-context.ts │ │ ├── middlewares │ │ │ └── cors.ts │ │ ├── failures │ │ │ ├── not-found-failure.ts │ │ │ ├── bad-request-failure.ts │ │ │ ├── forbidden-failure.ts │ │ │ ├── unauthorized-failure.ts │ │ │ ├── not-acceptable-failure.ts │ │ │ ├── payload-too-large-failure.ts │ │ │ ├── method-not-allowed-failure.ts │ │ │ └── unsupported-media-type-failure.ts │ │ ├── trie │ │ │ └── trie-node-already-exists-failure.ts │ │ ├── websocket │ │ │ └── websocket-response.ts │ │ └── context.ts │ ├── test │ │ └── fixtures │ │ │ └── make-headers-context.ts │ └── tsconfig.json ├── lib-protocol-utils │ ├── README.md │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── app-dev │ ├── src │ │ ├── constants │ │ │ ├── hosts.ts │ │ │ ├── paths.ts │ │ │ ├── entrypoints.ts │ │ │ └── ports.ts │ │ ├── signals │ │ │ ├── debug-scopes.ts │ │ │ ├── scenario.ts │ │ │ └── security-token.ts │ │ ├── types │ │ │ ├── shims.d.ts │ │ │ ├── runner-environment.ts │ │ │ └── development-base.ts │ │ ├── topics │ │ │ └── peer-traffic.ts │ │ ├── logger │ │ │ ├── namespaces.ts │ │ │ └── instances.ts │ │ ├── rpc-routers │ │ │ └── route-types │ │ │ │ └── base.ts │ │ ├── utils │ │ │ ├── vanity-node-id-to-friendly.ts │ │ │ ├── transformer.ts │ │ │ ├── prepare-data-directory.ts │ │ │ ├── shorten-node-id.ts │ │ │ └── check-file-status.ts │ │ ├── runner │ │ │ └── actors │ │ │ │ ├── handle-disconnect.ts │ │ │ │ ├── forward-logs.ts │ │ │ │ └── report-peering-state.ts │ │ ├── stores │ │ │ ├── peering-state.ts │ │ │ ├── additional-nodes.ts │ │ │ └── active-nodes.ts │ │ ├── scenarios │ │ │ ├── index.ts │ │ │ └── common.ts │ │ ├── actors │ │ │ └── apply-debug-logging-scopes.ts │ │ └── computed │ │ │ └── active-node-ids.ts │ └── vite.backend.config.js ├── app-dassie │ └── src │ │ ├── environment.d.ts │ │ ├── exchange │ │ ├── constants │ │ │ ├── internal-precision.ts │ │ │ └── currencies.ts │ │ ├── index.ts │ │ └── signals │ │ │ └── exchange-rates.ts │ │ ├── constants │ │ ├── cookie-name.ts │ │ ├── ui-query-parameter-names.ts │ │ ├── general.ts │ │ ├── object-identifiers.ts │ │ ├── bootstrap-nodes.ts │ │ └── seed-paths.ts │ │ ├── ilp-connector │ │ ├── constants │ │ │ └── max-packet-amount.ts │ │ ├── types │ │ │ ├── ilp-failure.ts │ │ │ └── ilp-address.ts │ │ ├── failures │ │ │ ├── unreachable-ilp-failure.ts │ │ │ ├── amount-too-large-ilp-failure.ts │ │ │ ├── internal-error-ilp-failure.ts │ │ │ ├── invalid-packet-ilp-failure.ts │ │ │ ├── insufficient-timeout-ilp-failure.ts │ │ │ ├── insufficient-liquidity-ilp-failure.ts │ │ │ └── base-ilp-failure.ts │ │ ├── values │ │ │ └── pending-packets-map.ts │ │ ├── computed │ │ │ ├── node-id.ts │ │ │ └── node-ilp-address.ts │ │ └── topics │ │ │ └── resolved-ilp-packet.ts │ │ ├── open-payments │ │ ├── constants │ │ │ └── payment-pointer.ts │ │ ├── schemas │ │ │ └── wallet.ts │ │ ├── tables │ │ │ ├── incoming-payment.ts │ │ │ └── outgoing-payment.ts │ │ └── index.ts │ │ ├── ilp-http │ │ ├── constants │ │ │ └── content-type.ts │ │ ├── values │ │ │ └── incoming-request-id-map.ts │ │ └── index.ts │ │ ├── ledgers │ │ ├── modules │ │ │ ├── xrpl │ │ │ │ ├── types │ │ │ │ │ └── peer-state.ts │ │ │ │ ├── oer-schemas │ │ │ │ │ ├── peering-response-data.ts │ │ │ │ │ ├── peering-info-data.ts │ │ │ │ │ ├── settlement-proof.ts │ │ │ │ │ └── peering-request-data.ts │ │ │ │ ├── constants │ │ │ │ │ ├── settlement-memo-type.ts │ │ │ │ │ └── asset-scale.ts │ │ │ │ ├── functions │ │ │ │ │ ├── load-wallet.ts │ │ │ │ │ └── get-account-info.ts │ │ │ │ └── utils │ │ │ │ │ └── is-rippled-error.ts │ │ │ └── index.ts │ │ ├── values │ │ │ └── pending-settlements-map.ts │ │ ├── database-tables │ │ │ └── settlement-schemes.ts │ │ ├── index.ts │ │ └── stores │ │ │ └── loaded-settlement-modules.ts │ │ ├── peer-protocol │ │ ├── types │ │ │ ├── settlement-scheme-id.ts │ │ │ └── node-id.ts │ │ ├── constants │ │ │ ├── content-type.ts │ │ │ └── anonymous-messages.ts │ │ ├── failures │ │ │ ├── invalid-link-state.ts │ │ │ └── uplink-address-query.ts │ │ ├── signals │ │ │ ├── bootstrap-node-lists.ts │ │ │ └── bootstrap-node-list-hashes.ts │ │ ├── tables │ │ │ ├── registrations.ts │ │ │ ├── nodes.ts │ │ │ └── peers.ts │ │ ├── utils │ │ │ ├── calculate-message-hmac.ts │ │ │ └── is-connection-refused-error.ts │ │ ├── handlers │ │ │ ├── node-list-hash-request.ts │ │ │ └── node-list-request.ts │ │ ├── computed │ │ │ ├── node-list-hash.ts │ │ │ └── x25519-private-key.ts │ │ ├── stores │ │ │ ├── incoming-session-keys.ts │ │ │ └── uplink-addresses.ts │ │ └── add-majority-nodes.ts │ │ ├── authentication │ │ ├── constants │ │ │ └── cookie-lifetime.ts │ │ ├── types │ │ │ └── session-token.ts │ │ ├── database-tables │ │ │ └── sessions.ts │ │ └── signals │ │ │ └── setup-authorization-token.ts │ │ ├── api-keys │ │ ├── types │ │ │ └── btp-token.ts │ │ └── database-tables │ │ │ └── btp-tokens.ts │ │ ├── http-server │ │ ├── values │ │ │ ├── http-router.ts │ │ │ ├── https-router.ts │ │ │ └── https-websocket-router.ts │ │ └── index.ts │ │ ├── command-line │ │ ├── entry.ts │ │ └── commands │ │ │ ├── daemon │ │ │ └── nodejs │ │ │ │ └── log-to-console.ts │ │ │ └── update │ │ │ └── download-file.ts │ │ ├── index.ts │ │ ├── accounting │ │ ├── topics │ │ │ ├── posted-transfers.ts │ │ │ ├── voided-transfers.ts │ │ │ └── pending-transfers.ts │ │ ├── failures │ │ │ ├── exceeds-debits.ts │ │ │ ├── exceeds-credits.ts │ │ │ └── invalid-account.ts │ │ ├── index.ts │ │ ├── utils │ │ │ └── cast-ledger-id.ts │ │ ├── database-tables │ │ │ └── accounts.ts │ │ ├── manage-builtin-accounts.ts │ │ ├── functions │ │ │ ├── get-ledger-id-from-path.ts │ │ │ └── manage-common-accounts.ts │ │ ├── constants │ │ │ └── ledgers.ts │ │ └── signals │ │ │ └── owner-ledger-id.ts │ │ ├── routing │ │ └── index.ts │ │ ├── acme-certificate-manager │ │ ├── constants │ │ │ └── acme-service.ts │ │ ├── tables │ │ │ └── acme-tokens.ts │ │ ├── index.ts │ │ └── schemas │ │ │ └── database-scalars.ts │ │ ├── local-ilp │ │ └── index.ts │ │ ├── rpc-server │ │ ├── route-types │ │ │ ├── public.ts │ │ │ └── protected.ts │ │ └── index.ts │ │ ├── config │ │ ├── schemas │ │ │ ├── node-id.ts │ │ │ └── settlement-scheme-id.ts │ │ ├── computed │ │ │ ├── has-tls.ts │ │ │ ├── has-node-identity.ts │ │ │ └── ilp-allocation-scheme.ts │ │ └── types │ │ │ └── environment-variables.ts │ │ ├── crypto │ │ ├── ed25519.ts │ │ ├── computed │ │ │ ├── node-public-key.ts │ │ │ └── node-private-key.ts │ │ └── functions │ │ │ └── sign-with-dassie-key.ts │ │ ├── utils │ │ ├── pretty-format.ts │ │ └── compare-typedarray.ts │ │ ├── base │ │ └── types │ │ │ └── dassie-base.ts │ │ ├── local-ipc-server │ │ └── index.ts │ │ ├── ildcp-server │ │ └── index.ts │ │ ├── btp-server │ │ └── index.ts │ │ ├── registration-client │ │ ├── constants │ │ │ └── threshold.ts │ │ └── rpc-router │ │ │ └── registration-client.ts │ │ ├── logger │ │ └── signals │ │ │ └── stdout-log-level.ts │ │ ├── public-api-server │ │ └── index.ts │ │ └── database │ │ └── migrations │ │ ├── 0008-create-sessions-table.ts │ │ ├── 0009-create-btp-tokens-table.ts │ │ ├── 0006-create-peers-table.ts │ │ ├── 0010-add-settlement-state-column.ts │ │ ├── 0005-create-nodes-table.ts │ │ ├── 0007-create-acme-tokens-table.ts │ │ ├── 0011-create-accounts-table.ts │ │ ├── 0013-create-registrations-table.ts │ │ └── 0001-create-scalar-table.ts ├── gui-dev │ ├── uno.config.ts │ ├── README.md │ ├── public │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── moon_map_mercator.jpg │ ├── vite.config.ts │ └── src │ │ ├── index.tsx │ │ ├── components │ │ ├── shared │ │ │ └── node-link │ │ │ │ └── node-link.tsx │ │ └── pages │ │ │ └── logs │ │ │ └── logs.tsx │ │ └── utils │ │ └── rpc.ts ├── app-website │ ├── uno.config.ts │ ├── src │ │ ├── env.d.ts │ │ ├── assets │ │ │ └── dassie.webp │ │ ├── content │ │ │ └── config.ts │ │ └── pages │ │ │ └── tools │ │ │ └── stream-toy.astro │ ├── README.md │ └── .gitignore ├── gui-dassie │ ├── uno.config.ts │ ├── README.md │ ├── src │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── android-chrome-192x192.png │ │ │ └── android-chrome-512x512.png │ │ ├── assets │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── apple-touch-icon.png │ │ │ └── site.webmanifest │ │ ├── components │ │ │ └── log-viewer │ │ │ │ └── ansi-theme.module.css │ │ ├── pages │ │ │ ├── payment-status │ │ │ │ └── payment-status.tsx │ │ │ ├── debug │ │ │ │ ├── routing │ │ │ │ │ └── detail │ │ │ │ │ │ └── peer.tsx │ │ │ │ ├── state │ │ │ │ │ └── signals │ │ │ │ │ │ └── signal-state.tsx │ │ │ │ └── logs │ │ │ │ │ └── logs.tsx │ │ │ ├── network │ │ │ │ └── node-detail │ │ │ │ │ └── own-node-detail.tsx │ │ │ └── setup │ │ │ │ └── setup-info.tsx │ │ ├── utils │ │ │ ├── rpc.ts │ │ │ ├── currency.ts │ │ │ └── signer.ts │ │ ├── constants │ │ │ ├── currency.ts │ │ │ ├── palette.ts │ │ │ └── schemes.ts │ │ ├── hooks │ │ │ └── use-account.ts │ │ ├── index.tsx │ │ └── types │ │ │ └── currency.ts │ ├── vite.config.ts │ └── tsconfig.json ├── lib-protocol-ildcp │ ├── src │ │ ├── address.ts │ │ ├── condition.ts │ │ ├── index.ts │ │ └── test │ │ │ └── fixtures │ │ │ └── packets.ts │ ├── README.md │ ├── rollup.config.js │ └── tsconfig.json ├── lib-format-utils │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── meta-eslint-plugin │ ├── test │ │ ├── fixture │ │ │ ├── file.ts │ │ │ ├── react.tsx │ │ │ ├── tsconfig.json │ │ │ └── failure.ts │ │ └── utils │ │ │ └── rule-tester.ts │ ├── src │ │ ├── utils │ │ │ ├── create-rule.ts │ │ │ └── is-top-level.ts │ │ └── configs │ │ │ └── recommended.ts │ ├── lib │ │ ├── utils │ │ │ ├── create-rule.js │ │ │ └── is-top-level.js │ │ └── configs │ │ │ └── recommended.js │ ├── tsconfig.json │ └── tsconfig.build.json ├── lib-logger │ ├── src │ │ ├── types │ │ │ ├── log-level.ts │ │ │ ├── formatter.ts │ │ │ └── log-event.ts │ │ ├── examples │ │ │ └── formatting │ │ │ │ ├── atomics.ts │ │ │ │ ├── keys.ts │ │ │ │ ├── promises.ts │ │ │ │ ├── getter.ts │ │ │ │ ├── functions.ts │ │ │ │ ├── errors.ts │ │ │ │ └── util │ │ │ │ └── compare.ts │ │ └── utils │ │ │ ├── is-async-function.ts │ │ │ ├── is-generator-function.ts │ │ │ ├── select-by-seed.ts │ │ │ ├── compare-level.ts │ │ │ ├── has-aggregated-errors.ts │ │ │ └── assert.ts │ ├── rollup.config.js │ └── tsconfig.json ├── lib-reactive │ ├── src │ │ ├── internal │ │ │ └── default-selector.ts │ │ ├── types │ │ │ ├── stateful-context.ts │ │ │ ├── cancelable-context.ts │ │ │ ├── factory.ts │ │ │ ├── execution-context.ts │ │ │ ├── scope-context.ts │ │ │ └── base-modules │ │ │ │ └── clock.ts │ │ ├── abstract.ts │ │ ├── constants │ │ │ └── crypto-algorithms.ts │ │ ├── failures │ │ │ └── decryption-failure.ts │ │ ├── test │ │ │ └── topic.test.ts │ │ ├── deferred.ts │ │ ├── examples │ │ │ └── base.ts │ │ ├── effect.ts │ │ └── tools │ │ │ └── abort-timeout.ts │ ├── CHANGELOG.md │ ├── rollup.config.js │ └── tsconfig.json ├── app-cli │ ├── index.js │ └── tsconfig.json ├── lib-protocol-ilp │ ├── README.md │ ├── rollup.config.js │ ├── tsconfig.json │ └── src │ │ └── io.ts ├── lib-reactive-rpc │ ├── README.md │ ├── src │ │ └── client │ │ │ └── rpc │ │ │ └── query-key.ts │ ├── CHANGELOG.md │ ├── tsconfig.json │ └── rollup.config.js ├── app-build │ ├── bin │ │ └── build.ts │ ├── src │ │ ├── constants │ │ │ ├── compression.ts │ │ │ ├── architectures.ts │ │ │ └── hashes.ts │ │ ├── utils │ │ │ ├── git.ts │ │ │ └── dynamic-paths.ts │ │ ├── steps │ │ │ ├── create-output-path.ts │ │ │ ├── clear-output-path.ts │ │ │ └── generate-metadata.ts │ │ └── cli-options │ │ │ └── architectures.ts │ ├── resources │ │ ├── launcher │ │ │ └── dassie.sh │ │ ├── systemd │ │ │ ├── dassie-update.service │ │ │ ├── dassie-http.socket │ │ │ ├── dassie-https.socket │ │ │ ├── dassie-update.timer │ │ │ └── dassie-ipc.socket │ │ └── binaries │ │ │ └── binary-dependencies.txt │ ├── vite.config.ts │ └── tsconfig.json ├── lib-terminal-graphics │ ├── src │ │ ├── constants │ │ │ └── ansi-codes.ts │ │ ├── types │ │ │ └── render-environment.ts │ │ ├── canceled.ts │ │ ├── examples │ │ │ └── text.ts │ │ ├── functions │ │ │ └── count-lines.ts │ │ ├── helpers │ │ │ ├── unicode-fallback.ts │ │ │ └── common-prefix-lines.ts │ │ ├── components │ │ │ ├── common │ │ │ │ └── actions │ │ │ │ │ └── finalizations.ts │ │ │ ├── text │ │ │ │ └── render-value-with-cursor.ts │ │ │ └── header.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── foreground-to-background-color.ts │ └── tsconfig.json ├── lib-rpc │ ├── src │ │ ├── common │ │ │ ├── rpc-success.ts │ │ │ ├── types │ │ │ │ ├── transformer.ts │ │ │ │ ├── nodejs-socket.ts │ │ │ │ ├── nodejs-messageport.ts │ │ │ │ └── websocket.ts │ │ │ ├── rpc-failure.ts │ │ │ ├── subscription.ts │ │ │ └── route-type.ts │ │ └── client │ │ │ └── id-generator.ts │ ├── CHANGELOG.md │ ├── README.md │ ├── rollup.config.js │ └── tsconfig.json ├── lib-type-utils │ ├── rollup.config.js │ ├── src │ │ ├── unreachable-case-error.ts │ │ ├── buffer-to-typedarray.ts │ │ ├── is-thenable.ts │ │ ├── array-equals.ts │ │ ├── assert-defined.ts │ │ ├── is-object.ts │ │ ├── bigint │ │ │ └── gcd.ts │ │ └── is-error-with-code.ts │ └── tsconfig.json ├── meta-incremental-check │ ├── src │ │ ├── meta-updater.ts │ │ ├── vitest.ts │ │ ├── constants │ │ │ └── workspace-path.ts │ │ ├── utils │ │ │ ├── get-file-date.ts │ │ │ ├── get-package-name.ts │ │ │ └── report-status.ts │ │ └── entry │ │ │ └── main.ts │ ├── vite.config.js │ └── tsconfig.json ├── lib-reactive-io │ ├── CHANGELOG.md │ ├── src │ │ ├── types │ │ │ └── runtime.ts │ │ ├── browser │ │ │ └── index.ts │ │ ├── node │ │ │ └── index.ts │ │ └── generic │ │ │ └── clock.ts │ ├── README.md │ ├── rollup.config.js │ └── tsconfig.json ├── lib-oer │ ├── src │ │ ├── utils │ │ │ ├── is-uint8array.ts │ │ │ ├── is-serializer.ts │ │ │ ├── errors.ts │ │ │ └── ensure-uint8array.ts │ │ ├── empty.ts │ │ └── information-object │ │ │ └── class.ts │ ├── rollup.config.js │ ├── test │ │ ├── utils │ │ │ ├── result.ts │ │ │ ├── sample-strings.ts │ │ │ └── sample-buffer.ts │ │ └── base-type.test.ts │ └── tsconfig.json ├── lib-protocol-stream │ ├── src │ │ ├── math │ │ │ ├── min-max.ts │ │ │ ├── ratio.ts │ │ │ └── failures │ │ │ │ └── amount-exceeds-maximum-receive-amount.ts │ │ ├── types │ │ │ ├── infer-topics.ts │ │ │ └── event-emitter.ts │ │ ├── connection │ │ │ ├── failures │ │ │ │ ├── no-exchange-rate-failure.ts │ │ │ │ ├── no-remote-address-failure.ts │ │ │ │ ├── probing-unsuccessful-failure.ts │ │ │ │ └── invalid-exchange-rate-failure.ts │ │ │ ├── mark-closed.ts │ │ │ └── create-stream.ts │ │ ├── server │ │ │ ├── failures │ │ │ │ └── configuration-detection-failure.ts │ │ │ └── generate-unique-id.ts │ │ ├── packets │ │ │ ├── expiry.ts │ │ │ └── parser.ts │ │ ├── stream │ │ │ ├── failures │ │ │ │ └── send-failure.ts │ │ │ ├── close.ts │ │ │ └── state.ts │ │ └── context │ │ │ └── context.ts │ ├── rollup.config.js │ └── CHANGELOG.md ├── lib-x509 │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── lib-itergen-utils │ ├── src │ │ ├── index.ts │ │ ├── iterate-multiple.ts │ │ ├── stream-prefix.ts │ │ └── stream-by-line.ts │ └── tsconfig.json ├── meta-tsconfig │ ├── vite-node.json │ ├── vite-isomorphic.json │ └── vite-react.json └── meta-unocss-config │ └── tsconfig.json ├── pnpm-workspace.yaml ├── eslint.config.mjs ├── vitest.workspace.ts ├── vitest.config.ts ├── .gitpod.yml ├── .vscode ├── extensions.json ├── tasks.json └── settings.json ├── .dockerignore ├── .editorconfig ├── .changeset ├── config.json └── README.md └── .prettierrc.json /.node-version: -------------------------------------------------------------------------------- 1 | v22.8.0 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /pnpm-lock.yaml 2 | dist/ -------------------------------------------------------------------------------- /packages/lib-sqlite/README.md: -------------------------------------------------------------------------------- 1 | # lib-sqlite 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - packages/* 3 | -------------------------------------------------------------------------------- /packages/lib-http-server/README.md: -------------------------------------------------------------------------------- 1 | # lib-http-server 2 | -------------------------------------------------------------------------------- /packages/lib-protocol-utils/README.md: -------------------------------------------------------------------------------- 1 | # lib-protocol-utils 2 | -------------------------------------------------------------------------------- /packages/lib-protocol-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./btp" 2 | -------------------------------------------------------------------------------- /packages/app-dev/src/constants/hosts.ts: -------------------------------------------------------------------------------- 1 | export const LOCALHOST = "127.0.0.1" 2 | -------------------------------------------------------------------------------- /packages/app-dassie/src/environment.d.ts: -------------------------------------------------------------------------------- 1 | declare const __DASSIE_VERSION__: string 2 | -------------------------------------------------------------------------------- /packages/gui-dev/uno.config.ts: -------------------------------------------------------------------------------- 1 | export { default } from "@dassie/meta-unocss-config" 2 | -------------------------------------------------------------------------------- /packages/app-website/uno.config.ts: -------------------------------------------------------------------------------- 1 | export { default } from "@dassie/meta-unocss-config" 2 | -------------------------------------------------------------------------------- /packages/gui-dassie/uno.config.ts: -------------------------------------------------------------------------------- 1 | export { default } from "@dassie/meta-unocss-config" 2 | -------------------------------------------------------------------------------- /packages/lib-protocol-ildcp/src/address.ts: -------------------------------------------------------------------------------- 1 | export const ILDCP_ADDRESS = "peer.config" 2 | -------------------------------------------------------------------------------- /packages/lib-format-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export { formatTypedArrayPlugin } from "./typed-array" 2 | -------------------------------------------------------------------------------- /packages/lib-sqlite/src/utils/identity.ts: -------------------------------------------------------------------------------- 1 | export const identity = (value: T): T => value 2 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import config from "@dassie/meta-eslint-config" 2 | 3 | export default config 4 | -------------------------------------------------------------------------------- /packages/gui-dassie/README.md: -------------------------------------------------------------------------------- 1 | # gui-dassie 2 | 3 | This package contains the Dassie node frontend. 4 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/test/fixture/file.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line unicorn/no-empty-file 2 | -------------------------------------------------------------------------------- /packages/app-dassie/src/exchange/constants/internal-precision.ts: -------------------------------------------------------------------------------- 1 | export const INTERNAL_PRECISION = 15 2 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_MAX_BODY_SIZE = 1024 * 1024 * 2 // 2 MB 2 | -------------------------------------------------------------------------------- /packages/lib-logger/src/types/log-level.ts: -------------------------------------------------------------------------------- 1 | export type LogLevel = "debug" | "info" | "warn" | "error" 2 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/test/fixture/react.tsx: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line unicorn/no-empty-file 2 | -------------------------------------------------------------------------------- /packages/app-dassie/src/constants/cookie-name.ts: -------------------------------------------------------------------------------- 1 | export const SESSION_COOKIE_NAME = "__Host-Dassie-Session" 2 | -------------------------------------------------------------------------------- /packages/gui-dev/README.md: -------------------------------------------------------------------------------- 1 | # gui-dev 2 | 3 | This package contains the frontend for the development server. 4 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/internal/default-selector.ts: -------------------------------------------------------------------------------- 1 | export const defaultSelector = (value: T) => value 2 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/constants/max-packet-amount.ts: -------------------------------------------------------------------------------- 1 | export const MAX_PACKET_AMOUNT = 100_000_000n 2 | -------------------------------------------------------------------------------- /packages/gui-dev/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dev/public/favicon.ico -------------------------------------------------------------------------------- /packages/app-dassie/src/open-payments/constants/payment-pointer.ts: -------------------------------------------------------------------------------- 1 | export const PAYMENT_POINTER_PATH = "/.well-known/pay" 2 | -------------------------------------------------------------------------------- /packages/app-website/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/types/environment.d.ts: -------------------------------------------------------------------------------- 1 | interface ResponseInit { 2 | statusText?: string | undefined 3 | } 4 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-http/constants/content-type.ts: -------------------------------------------------------------------------------- 1 | export const ILP_OVER_HTTP_CONTENT_TYPE = "application/octet-stream" 2 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/types/peer-state.ts: -------------------------------------------------------------------------------- 1 | export interface XrplPeerState { 2 | address: string 3 | } 4 | -------------------------------------------------------------------------------- /packages/gui-dev/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dev/public/favicon-16x16.png -------------------------------------------------------------------------------- /packages/gui-dev/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dev/public/favicon-32x32.png -------------------------------------------------------------------------------- /packages/app-cli/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // eslint-disable-next-line no-console 4 | console.log(`🐻 Dassie is here!`) 5 | -------------------------------------------------------------------------------- /packages/app-dassie/src/constants/ui-query-parameter-names.ts: -------------------------------------------------------------------------------- 1 | export const QUERY_PARAMETER_DEVELOPMENT_SESSION = "_DASSIE_DEV_SESSION" 2 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/types/settlement-scheme-id.ts: -------------------------------------------------------------------------------- 1 | export type SettlementSchemeId = "stub" | "xrpl" | "xrpl-testnet" 2 | -------------------------------------------------------------------------------- /packages/app-website/src/assets/dassie.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/app-website/src/assets/dassie.webp -------------------------------------------------------------------------------- /packages/gui-dassie/src/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dassie/src/public/favicon.ico -------------------------------------------------------------------------------- /packages/lib-protocol-ilp/README.md: -------------------------------------------------------------------------------- 1 | # lib-protocol-ilp 2 | 3 | This module provides ILP packet serialization and deserialization. 4 | -------------------------------------------------------------------------------- /packages/lib-reactive-rpc/README.md: -------------------------------------------------------------------------------- 1 | # lib-reactive-rpc 2 | 3 | Provides hooks for using lib-reactive and lib-rpc in React frontends. 4 | -------------------------------------------------------------------------------- /vitest.workspace.ts: -------------------------------------------------------------------------------- 1 | import { defineWorkspace } from "vitest/config" 2 | 3 | export default defineWorkspace(["./vitest.config.ts"]) 4 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/constants/content-type.ts: -------------------------------------------------------------------------------- 1 | export const DASSIE_MESSAGE_CONTENT_TYPE = "application/dassie-message" 2 | -------------------------------------------------------------------------------- /packages/gui-dev/public/moon_map_mercator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dev/public/moon_map_mercator.jpg -------------------------------------------------------------------------------- /packages/lib-protocol-ildcp/README.md: -------------------------------------------------------------------------------- 1 | # lib-protocol-ildcp 2 | 3 | This module provides parsing and serialization for IL-DCP responses. 4 | -------------------------------------------------------------------------------- /packages/app-dassie/src/authentication/constants/cookie-lifetime.ts: -------------------------------------------------------------------------------- 1 | export const COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365 * 10 // 10 years 2 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dassie/src/assets/favicon-16x16.png -------------------------------------------------------------------------------- /packages/gui-dassie/src/assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dassie/src/assets/favicon-32x32.png -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/types/node-id.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | export type NodeId = Tagged 4 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/assets/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dassie/src/assets/apple-touch-icon.png -------------------------------------------------------------------------------- /packages/app-build/bin/build.ts: -------------------------------------------------------------------------------- 1 | import process from "node:process" 2 | 3 | import { build } from "../src" 4 | 5 | await build(process.argv.slice(2)) 6 | -------------------------------------------------------------------------------- /packages/app-dassie/src/api-keys/types/btp-token.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | export type BtpToken = Tagged 4 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/constants/ansi-codes.ts: -------------------------------------------------------------------------------- 1 | export const CLEAR_TO_END_OF_LINE = "\u001B[K" 2 | export const CLEAR_REST_OF_SCREEN = "\u001B[0J" 3 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dassie/src/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /packages/gui-dassie/src/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justmoon/dassie/HEAD/packages/gui-dassie/src/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /packages/lib-http-server/src/types/http-response.ts: -------------------------------------------------------------------------------- 1 | import type { HttpResult } from "./http-result" 2 | 3 | export interface HttpResponse extends HttpResult {} 4 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/rpc-success.ts: -------------------------------------------------------------------------------- 1 | export class RpcSuccess { 2 | name = "RpcSuccess" 3 | 4 | constructor(public readonly data: T) {} 5 | } 6 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/types/transformer.ts: -------------------------------------------------------------------------------- 1 | export interface Transformer { 2 | stringify(value: unknown): string 3 | parse(value: string): unknown 4 | } 5 | -------------------------------------------------------------------------------- /packages/app-dassie/src/authentication/types/session-token.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | export type SessionToken = Tagged 4 | -------------------------------------------------------------------------------- /packages/app-dassie/src/http-server/values/http-router.ts: -------------------------------------------------------------------------------- 1 | import { createRouter } from "@dassie/lib-http-server" 2 | 3 | export const HttpRouter = () => createRouter() 4 | -------------------------------------------------------------------------------- /packages/lib-type-utils/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [...entrypoint()] 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /packages/app-dassie/src/http-server/values/https-router.ts: -------------------------------------------------------------------------------- 1 | import { createRouter } from "@dassie/lib-http-server" 2 | 3 | export const HttpsRouter = () => createRouter() 4 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config" 2 | 3 | export default defineConfig({ 4 | test: { 5 | includeSource: ["**/*.{js,ts}"], 6 | }, 7 | }) 8 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/oer-schemas/peering-response-data.ts: -------------------------------------------------------------------------------- 1 | import { empty } from "@dassie/lib-oer" 2 | 3 | export const peeringResponseSchema = empty() 4 | -------------------------------------------------------------------------------- /packages/lib-logger/src/examples/formatting/atomics.ts: -------------------------------------------------------------------------------- 1 | import { showComparison } from "./util/compare" 2 | 3 | const atomics = Atomics 4 | 5 | showComparison(atomics, "Atomics") 6 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/client/id-generator.ts: -------------------------------------------------------------------------------- 1 | export function createIdGenerator() { 2 | let id = 0 3 | return function generateId() { 4 | return String(id++) 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/test/fixture/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true 4 | }, 5 | "include": ["failure.ts", "file.ts", "react.tsx"] 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-build/src/constants/compression.ts: -------------------------------------------------------------------------------- 1 | export const SUPPORTED_COMPRESSIONS = ["gz", "xz"] as const 2 | 3 | export type Compression = (typeof SUPPORTED_COMPRESSIONS)[number] 4 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/utils/normalize-path.ts: -------------------------------------------------------------------------------- 1 | export function normalizePath(path: string): string[] { 2 | return path.replace(/^\//, "").replace(/\/$/, "").split("/") 3 | } 4 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/src/meta-updater.ts: -------------------------------------------------------------------------------- 1 | import update from "@pnpm/meta-updater" 2 | 3 | export async function runMetaUpdater() { 4 | await update({ test: true }) 5 | } 6 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: | 3 | pnpm install 4 | pnpm build 5 | command: | 6 | pnpm start 7 | ports: 8 | - port: 3000 9 | onOpen: open-preview 10 | -------------------------------------------------------------------------------- /packages/lib-reactive-io/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dassie/lib-reactive-io 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [6db37bc] 8 | - @dassie/lib-reactive@0.0.1 9 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/src/vitest.ts: -------------------------------------------------------------------------------- 1 | import { startVitest } from "vitest/node" 2 | 3 | export async function runVitest() { 4 | await startVitest("test", [], { run: true }) 5 | } 6 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/utils/is-dynamic-path.ts: -------------------------------------------------------------------------------- 1 | export function isDynamicPath(path: string[]): boolean { 2 | return path.some((segment) => segment.startsWith(":") || segment === "*") 3 | } 4 | -------------------------------------------------------------------------------- /packages/lib-oer/src/utils/is-uint8array.ts: -------------------------------------------------------------------------------- 1 | export const isUint8Array = (value: unknown): value is Uint8Array => { 2 | return Object.prototype.toString.call(value) === "[object Uint8Array]" 3 | } 4 | -------------------------------------------------------------------------------- /packages/lib-reactive/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dassie/lib-reactive 2 | 3 | ## 0.0.1 4 | 5 | ### Patch Changes 6 | 7 | - 6db37bc: Add the ability to seed the mock deterministic crypto module with a string 8 | -------------------------------------------------------------------------------- /packages/app-dev/src/signals/debug-scopes.ts: -------------------------------------------------------------------------------- 1 | import { createSignal } from "@dassie/lib-reactive" 2 | 3 | export const DebugScopesSignal = () => 4 | createSignal(process.env["DEBUG"] ?? "das:*,ilp*") 5 | -------------------------------------------------------------------------------- /packages/lib-reactive-io/src/types/runtime.ts: -------------------------------------------------------------------------------- 1 | import type { Clock, Crypto } from "@dassie/lib-reactive" 2 | 3 | export interface Runtime { 4 | readonly clock: Clock 5 | readonly crypto: Crypto 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/types/stateful-context.ts: -------------------------------------------------------------------------------- 1 | import type { Reactor } from "../reactor" 2 | 3 | export interface StatefulContext { 4 | readonly reactor: Reactor 5 | } 6 | -------------------------------------------------------------------------------- /packages/lib-type-utils/src/unreachable-case-error.ts: -------------------------------------------------------------------------------- 1 | export class UnreachableCaseError extends Error { 2 | constructor(value: never) { 3 | super(`Unreachable case: ${String(value)}`) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/app-dassie/src/http-server/values/https-websocket-router.ts: -------------------------------------------------------------------------------- 1 | import { createWebSocketRouter } from "@dassie/lib-http-server" 2 | 3 | export const HttpsWebSocketRouter = () => createWebSocketRouter() 4 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/constants/settlement-memo-type.ts: -------------------------------------------------------------------------------- 1 | export const XRP_SETTLEMENT_MEMO_TYPE = Buffer.from( 2 | "https://dassie.land/settlement/xrp-testnet/v1", 3 | ).toString("hex") 4 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/values/pending-settlements-map.ts: -------------------------------------------------------------------------------- 1 | import type { Transfer } from "../../accounting/stores/ledger" 2 | 3 | export const PendingSettlementsMap = () => new Map() 4 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/types/http-result.ts: -------------------------------------------------------------------------------- 1 | import type { BaseRequestContext } from "./context" 2 | 3 | export interface HttpResult { 4 | asResponse: (context: BaseRequestContext) => Response 5 | } 6 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/types/render-environment.ts: -------------------------------------------------------------------------------- 1 | import type { PromptTheme } from "../theme" 2 | 3 | export interface RenderEnvironment { 4 | columns: number 5 | theme: PromptTheme 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-type-utils/src/buffer-to-typedarray.ts: -------------------------------------------------------------------------------- 1 | export const bufferToUint8Array = (buffer: Buffer): Uint8Array => { 2 | return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) 3 | } 4 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/math/min-max.ts: -------------------------------------------------------------------------------- 1 | export function min(a: bigint, b: bigint) { 2 | return a < b ? a : b 3 | } 4 | 5 | export function max(a: bigint, b: bigint) { 6 | return a > b ? a : b 7 | } 8 | -------------------------------------------------------------------------------- /packages/lib-x509/src/index.ts: -------------------------------------------------------------------------------- 1 | export { parseEd25519Key, serializeEd25519Key } from "./ed25519" 2 | export { parsePem, serializePem } from "./pem" 3 | export { generateSelfSignedCertificate } from "./self-signed" 4 | -------------------------------------------------------------------------------- /packages/lib-itergen-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as byLine } from "./stream-by-line" 2 | export { default as iterateMultiple } from "./iterate-multiple" 3 | export { default as prefix } from "./stream-prefix" 4 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/abstract.ts: -------------------------------------------------------------------------------- 1 | export const createAbstract = (): T => { 2 | throw new Error( 3 | "This value is abstract and therefore must be explicitly injected into the Reactor before use", 4 | ) 5 | } 6 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/src/constants/workspace-path.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path" 2 | 3 | export const WORKSPACE_ROOT_PATH = path.resolve( 4 | new URL(import.meta.url).pathname, 5 | "../../../../../", 6 | ) 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/command-line/entry.ts: -------------------------------------------------------------------------------- 1 | import { createReactor } from "@dassie/lib-reactive" 2 | 3 | import { main } from "." 4 | 5 | const reactor = createReactor() 6 | await main(reactor) 7 | await reactor.dispose() 8 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/oer-schemas/peering-info-data.ts: -------------------------------------------------------------------------------- 1 | import { ia5String, sequence } from "@dassie/lib-oer" 2 | 3 | export const peeringInfoSchema = sequence({ 4 | address: ia5String([25, 35]), 5 | }) 6 | -------------------------------------------------------------------------------- /packages/lib-logger/src/utils/is-async-function.ts: -------------------------------------------------------------------------------- 1 | export const isAsyncFunction = (value: unknown) => 2 | typeof value === "function" && 3 | Symbol.toStringTag in value && 4 | value[Symbol.toStringTag] === "AsyncFunction" 5 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/src/utils/create-rule.ts: -------------------------------------------------------------------------------- 1 | import { ESLintUtils } from "@typescript-eslint/utils" 2 | 3 | export const createRule = ESLintUtils.RuleCreator( 4 | (name) => `https://dassie.land/rule/${name}`, 5 | ) 6 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/types/ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export interface IlpFailure extends Failure { 4 | readonly errorCode: string 5 | readonly message: string 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-dev/src/types/shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module "launch-editor" { 2 | const launchEditor: ( 3 | location: string, 4 | editor?: string, 5 | callback?: () => void, 6 | ) => void 7 | export = launchEditor 8 | } 9 | -------------------------------------------------------------------------------- /packages/lib-itergen-utils/src/iterate-multiple.ts: -------------------------------------------------------------------------------- 1 | export default function* iterateMultiple( 2 | ...iterables: Iterable[] 3 | ): Iterable { 4 | for (const iterable of iterables) { 5 | yield* iterable 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/canceled.ts: -------------------------------------------------------------------------------- 1 | export const Canceled = Symbol("Canceled") 2 | export type Canceled = typeof Canceled 3 | 4 | export const isCanceled = (value: unknown): value is Canceled => 5 | value === Canceled 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "antfu.unocss", 4 | "unifiedjs.vscode-mdx", 5 | "astro-build.astro-vscode", 6 | "dbaeumer.vscode-eslint", 7 | "esbenp.prettier-vscode" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/oer-schemas/settlement-proof.ts: -------------------------------------------------------------------------------- 1 | import { octetString, sequence } from "@dassie/lib-oer" 2 | 3 | export const settlementProofSchema = sequence({ 4 | transactionHash: octetString(32), 5 | }) 6 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/middlewares/cors.ts: -------------------------------------------------------------------------------- 1 | import type { Middleware } from "../router" 2 | 3 | export const cors: Middleware<{}, object> = ({ response: { headers } }) => { 4 | headers.set("Access-Control-Allow-Origin", "*") 5 | } 6 | -------------------------------------------------------------------------------- /packages/lib-logger/src/utils/is-generator-function.ts: -------------------------------------------------------------------------------- 1 | export const isGeneratorFunction = (value: unknown) => 2 | typeof value === "function" && 3 | Symbol.toStringTag in value && 4 | value[Symbol.toStringTag] === "GeneratorFunction" 5 | -------------------------------------------------------------------------------- /packages/lib-reactive-rpc/src/client/rpc/query-key.ts: -------------------------------------------------------------------------------- 1 | export function getQueryKey( 2 | path: string[], 3 | type: "query" | "mutation" | "subscription", 4 | input: unknown, 5 | ) { 6 | return ["rpc", path, { input, type }] 7 | } 8 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/types/cancelable-context.ts: -------------------------------------------------------------------------------- 1 | import type { Cancellable } from "../cancellation" 2 | 3 | export interface CancelableContext { 4 | readonly cancellable: Cancellable 5 | readonly abortSignal: AbortSignal 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-build/resources/launcher/dassie.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BIN_FOLDER="$(dirname "$(readlink -f "$0")")" 4 | DASSIE_ROOT="$(dirname "$BIN_FOLDER")" 5 | 6 | export DASSIE_ROOT 7 | 8 | exec "$BIN_FOLDER/node" "$DASSIE_ROOT/backend.mjs" "$@" -------------------------------------------------------------------------------- /packages/app-build/src/utils/git.ts: -------------------------------------------------------------------------------- 1 | import { $ } from "execa" 2 | 3 | export const getHeadCommitShort = async () => { 4 | const gitResult = await $`git -c safe.directory=* rev-parse --short HEAD` 5 | return gitResult.stdout.trim() 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-build/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | 3 | export default defineConfig({ 4 | plugins: [], 5 | server: { 6 | hmr: true, 7 | }, 8 | build: { 9 | target: "esnext", 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/constants/asset-scale.ts: -------------------------------------------------------------------------------- 1 | export const XRP_ON_LEDGER_SCALE = 6 2 | export const XRP_INTERNAL_SCALE = 9 3 | export const XRP_VALUE_FACTOR = 4 | 10n ** BigInt(XRP_INTERNAL_SCALE - XRP_ON_LEDGER_SCALE) 5 | -------------------------------------------------------------------------------- /packages/app-dev/src/constants/paths.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path" 2 | 3 | export const LOCAL_FOLDER = new URL("../../../../local/", import.meta.url) 4 | .pathname 5 | 6 | export const DEV_SERVER_STATE_PATH = path.resolve(LOCAL_FOLDER, "dev/") 7 | -------------------------------------------------------------------------------- /packages/app-dev/src/signals/scenario.ts: -------------------------------------------------------------------------------- 1 | import { createSignal } from "@dassie/lib-reactive" 2 | 3 | import type { scenarios } from "../scenarios" 4 | 5 | export const ScenarioSignal = () => 6 | createSignal("two-nodes") 7 | -------------------------------------------------------------------------------- /packages/app-dev/vite.backend.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | 3 | export default defineConfig({ 4 | plugins: [], 5 | server: { 6 | hmr: true, 7 | }, 8 | build: { 9 | target: "esnext", 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /packages/lib-oer/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("index", { 5 | external: ["@dassie/lib-type-utils"], 6 | }), 7 | ] 8 | 9 | export default config 10 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/types/infer-topics.ts: -------------------------------------------------------------------------------- 1 | import type { Topic } from "@dassie/lib-reactive" 2 | 3 | export type InferTopics> = { 4 | [K in keyof TEventTypes]: Topic 5 | } 6 | -------------------------------------------------------------------------------- /packages/lib-type-utils/src/is-thenable.ts: -------------------------------------------------------------------------------- 1 | import { isObject } from "./is-object" 2 | 3 | export const isThenable = (value: unknown): value is PromiseLike => 4 | isObject(value) && "then" in value && typeof value["then"] === "function" 5 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/functions/load-wallet.ts: -------------------------------------------------------------------------------- 1 | import { Wallet, encodeSeed } from "xrpl" 2 | 3 | export const loadOrCreateWallet = (seed: Uint8Array): Wallet => { 4 | return Wallet.fromSeed(encodeSeed(seed, "ed25519")) 5 | } 6 | -------------------------------------------------------------------------------- /packages/app-website/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection } from 'astro:content'; 2 | import { docsSchema } from '@astrojs/starlight/schema'; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | }; 7 | -------------------------------------------------------------------------------- /packages/lib-reactive/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("index", { 5 | external: ["@dassie/lib-type-utils"], 6 | }), 7 | ] 8 | 9 | export default config 10 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | 3 | export default defineConfig({ 4 | plugins: [], 5 | server: { 6 | hmr: true, 7 | }, 8 | build: { 9 | target: "esnext", 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /packages/app-build/resources/systemd/dassie-update.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Update Dassie to the latest version 3 | Documentation=https://dassie.land/ 4 | 5 | [Service] 6 | Type=oneshot 7 | User=root 8 | ExecStart=/opt/dassie/current/bin/dassie update 9 | -------------------------------------------------------------------------------- /packages/app-dassie/src/constants/general.ts: -------------------------------------------------------------------------------- 1 | export const APP_NAME = "dassie-node" 2 | 3 | export const VALID_REALMS = ["test", "live"] as const 4 | 5 | export const EMPTY_UINT8ARRAY = new Uint8Array(0) 6 | 7 | export const DEV_SECURITY_TOKEN_LENGTH = 64 8 | -------------------------------------------------------------------------------- /packages/lib-protocol-ildcp/src/condition.ts: -------------------------------------------------------------------------------- 1 | export const ILDCP_CONDITION = new Uint8Array([ 2 | 102, 104, 122, 173, 248, 98, 189, 119, 108, 143, 193, 139, 142, 159, 142, 32, 3 | 8, 151, 20, 133, 110, 226, 51, 179, 144, 42, 89, 29, 13, 95, 41, 37, 4 | ]) 5 | -------------------------------------------------------------------------------- /packages/lib-type-utils/src/array-equals.ts: -------------------------------------------------------------------------------- 1 | export const arrayEquals = (a: readonly unknown[], b: readonly unknown[]) => 2 | Array.isArray(a) && 3 | Array.isArray(b) && 4 | a.length === b.length && 5 | a.every((value, index) => b[index] === value) 6 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/not-found-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class NotFoundFailure extends DefaultHttpFailure { 4 | readonly name = "NotFoundFailure" 5 | readonly statusCode = 404 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/index.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/triple-slash-reference 2 | /// 3 | 4 | export { AttachLogger } from "./logger/functions/attach-logger" 5 | export { DaemonActor } from "./daemon" 6 | -------------------------------------------------------------------------------- /packages/app-dev/src/topics/peer-traffic.ts: -------------------------------------------------------------------------------- 1 | import { createTopic } from "@dassie/lib-reactive" 2 | 3 | export interface PeerMessageMetadata { 4 | from: string 5 | to: string 6 | } 7 | 8 | export const PeerTrafficTopic = () => createTopic() 9 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/bad-request-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class BadRequestFailure extends DefaultHttpFailure { 4 | readonly name = "BadRequestFailure" 5 | readonly statusCode = 400 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/forbidden-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class ForbiddenFailure extends DefaultHttpFailure { 4 | readonly name = "ForbiddenFailure" 5 | readonly statusCode = 403 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/rpc-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class RpcFailure extends Failure { 4 | name = "RpcFailure" 5 | 6 | constructor(public readonly message: string) { 7 | super() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/lib-type-utils/src/assert-defined.ts: -------------------------------------------------------------------------------- 1 | export function assertDefined( 2 | value: T | null | undefined, 3 | ): asserts value is T { 4 | if (value == undefined) { 5 | throw new Error(`value ${String(value)} must not be null/undefined.`) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/topics/posted-transfers.ts: -------------------------------------------------------------------------------- 1 | import { createTopic } from "@dassie/lib-reactive" 2 | 3 | import type { Transfer } from "../stores/ledger" 4 | 5 | export const PostedTransfersTopic = () => 6 | createTopic() 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/topics/voided-transfers.ts: -------------------------------------------------------------------------------- 1 | import { createTopic } from "@dassie/lib-reactive" 2 | 3 | import type { Transfer } from "../stores/ledger" 4 | 5 | export const VoidedTransfersTopic = () => 6 | createTopic() 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-http/values/incoming-request-id-map.ts: -------------------------------------------------------------------------------- 1 | interface IlpHttpRequestEntry { 2 | requestId: string 3 | callbackUrl: string 4 | } 5 | 6 | export const IncomingRequestIdMap = () => { 7 | return new Map() 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-website/README.md: -------------------------------------------------------------------------------- 1 | # [Dassie.land](https://dassie.land) 2 | 3 | [![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) 4 | 5 | This is the source code for the [dassie.land](https://dassie.land) website. 6 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/unauthorized-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class UnauthorizedFailure extends DefaultHttpFailure { 4 | readonly name = "UnauthorizedFailure" 5 | readonly statusCode = 401 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/math/ratio.ts: -------------------------------------------------------------------------------- 1 | export type Ratio = [numerator: bigint, denominator: bigint] 2 | 3 | export function multiplyByRatio( 4 | value: bigint, 5 | [numerator, denominator]: Ratio, 6 | ) { 7 | return (value * numerator) / denominator 8 | } 9 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/constants/crypto-algorithms.ts: -------------------------------------------------------------------------------- 1 | export const HASH_ALGORITHMS = ["sha256", "sha512"] as const 2 | export const MAC_ALGORITHMS = ["hmac-sha256", "hmac-sha512"] as const 3 | export const ENCRYPTION_ALGORITHMS = ["aes-128-gcm", "aes-256-gcm"] as const 4 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/topics/pending-transfers.ts: -------------------------------------------------------------------------------- 1 | import { createTopic } from "@dassie/lib-reactive" 2 | 3 | import type { Transfer } from "../stores/ledger" 4 | 5 | export const PendingTransfersTopic = () => 6 | createTopic() 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/routing/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import { CalculateRoutesActor } from "./calculate-routes" 4 | 5 | export const RoutingActor = () => 6 | createActor((sig) => { 7 | sig.run(CalculateRoutesActor) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/not-acceptable-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class NotAcceptableFailure extends DefaultHttpFailure { 4 | readonly name = "NotAcceptableError" 5 | readonly statusCode = 406 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-protocol-ildcp/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("index", { 5 | external: ["@dassie/lib-oer", "@dassie/lib-type-utils"], 6 | }), 7 | ] 8 | 9 | export default config 10 | -------------------------------------------------------------------------------- /packages/lib-protocol-ildcp/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | type IldcpResponse, 3 | ildcpResponseSchema, 4 | parseIldcpResponse, 5 | serializeIldcpResponse, 6 | } from "./schema" 7 | export { ILDCP_ADDRESS } from "./address" 8 | export { ILDCP_CONDITION } from "./condition" 9 | -------------------------------------------------------------------------------- /packages/lib-protocol-ilp/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("index", { 5 | external: ["@dassie/lib-type-utils", "@dassie/lib-oer"], 6 | }), 7 | ] 8 | 9 | export default config 10 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/failures/decryption-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class DecryptionFailure extends Failure { 4 | readonly name = "DecryptionFailure" 5 | } 6 | 7 | export const DECRYPTION_FAILURE = new DecryptionFailure() 8 | -------------------------------------------------------------------------------- /packages/lib-sqlite/test/utils/dump-table.ts: -------------------------------------------------------------------------------- 1 | import type { AnyDatabase } from "../../src" 2 | 3 | export const dumpTable = (database: AnyDatabase, tableName: string) => { 4 | const rows = database.raw.prepare(`SELECT * FROM ${tableName}`).all() 5 | 6 | return rows 7 | } 8 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/payload-too-large-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class PayloadTooLargeFailure extends DefaultHttpFailure { 4 | readonly name = "PayloadTooLargeError" 5 | readonly statusCode = 413 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/acme-certificate-manager/constants/acme-service.ts: -------------------------------------------------------------------------------- 1 | import { directory as acmeDirectory } from "acme-client" 2 | 3 | export const ACME_DIRECTORY_URL = 4 | import.meta.env.DEV ? 5 | acmeDirectory.letsencrypt.staging 6 | : acmeDirectory.letsencrypt.production 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/failures/unreachable-ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { BaseIlpFailure } from "./base-ilp-failure" 2 | 3 | export class UnreachableIlpFailure extends BaseIlpFailure { 4 | readonly errorCode = "F02" as const 5 | readonly name = "UnreachableIlpFailure" 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-dev/src/logger/namespaces.ts: -------------------------------------------------------------------------------- 1 | export const LOGGER_CHILDREN = "das:dev:children" 2 | export const LOGGER_RUNNER = "das:dev:runner" 3 | export const LOGGER_SETUP = "das:dev:setup" 4 | export const LOGGER_SERVER = "das:dev:server" 5 | export const LOGGER_VITE = "das:dev:vite" 6 | -------------------------------------------------------------------------------- /packages/app-dev/src/rpc-routers/route-types/base.ts: -------------------------------------------------------------------------------- 1 | import type { ActorContext, Reactor } from "@dassie/lib-reactive" 2 | import { createRoute } from "@dassie/lib-rpc/server" 3 | 4 | export const baseRoute = createRoute().context<{ 5 | sig: ActorContext 6 | reactor: Reactor 7 | }>() 8 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/components/log-viewer/ansi-theme.module.css: -------------------------------------------------------------------------------- 1 | @keyframes blink { 2 | 0%, 3 | 50% { 4 | visibility: visible; 5 | } 6 | 7 | 100% { 8 | visibility: hidden; 9 | } 10 | } 11 | 12 | .blink { 13 | animation: blink 2s linear infinite; 14 | } 15 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/method-not-allowed-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class MethodNotAllowedFailure extends DefaultHttpFailure { 4 | readonly name = "MethodNotAllowedFailure" 5 | readonly statusCode = 405 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/subscription.ts: -------------------------------------------------------------------------------- 1 | export type Disposer = () => void 2 | export type Subscription = (onData: (value: T) => void) => Disposer 3 | 4 | export function createSubscription( 5 | subscribe: Subscription, 6 | ): Subscription { 7 | return subscribe 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-build/resources/systemd/dassie-http.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Dassie Public HTTP Socket 3 | Documentation=https://dassie.land/ 4 | 5 | [Socket] 6 | ListenStream=0.0.0.0:80 7 | NoDelay=true 8 | Service=dassie.service 9 | 10 | [Install] 11 | WantedBy=sockets.target 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/exchange/constants/currencies.ts: -------------------------------------------------------------------------------- 1 | export const CURRENCIES = { 2 | USD: { 3 | code: "USD", 4 | scale: 9, 5 | }, 6 | XRP: { 7 | code: "XRP", 8 | scale: 9, 9 | }, 10 | } as const 11 | 12 | export type CurrencyId = keyof typeof CURRENCIES 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/local-ilp/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import { RouteLocalEndpointsActor } from "./route-local-endpoints" 4 | 5 | export const LocalIlpActor = () => 6 | createActor((sig) => { 7 | sig.run(RouteLocalEndpointsActor) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/app-dev/src/constants/entrypoints.ts: -------------------------------------------------------------------------------- 1 | export const DEVELOPMENT_SERVER_ENTRYPOINT = new URL( 2 | "../start.ts", 3 | import.meta.url, 4 | ).pathname 5 | 6 | export const NODE_ENTRYPOINT = new URL( 7 | "../runner/launchers/node.ts", 8 | import.meta.url, 9 | ).pathname 10 | -------------------------------------------------------------------------------- /packages/lib-itergen-utils/src/stream-prefix.ts: -------------------------------------------------------------------------------- 1 | const prefix = (prefix: string) => 2 | async function* (chunks: AsyncIterable): AsyncIterable { 3 | for await (const chunk of chunks) { 4 | yield `${prefix}${chunk}` 5 | } 6 | } 7 | 8 | export default prefix 9 | -------------------------------------------------------------------------------- /packages/lib-oer/src/utils/is-serializer.ts: -------------------------------------------------------------------------------- 1 | import type { Serializer } from "../base-type" 2 | 3 | export const isSerializer = (input: unknown): input is Serializer => { 4 | return ( 5 | typeof input === "function" && 6 | typeof (input as Serializer).size === "number" 7 | ) 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-build/resources/systemd/dassie-https.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Dassie Public HTTPS Socket 3 | Documentation=https://dassie.land/ 4 | 5 | [Socket] 6 | ListenStream=0.0.0.0:443 7 | NoDelay=true 8 | Service=dassie.service 9 | 10 | [Install] 11 | WantedBy=sockets.target 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/failures/amount-too-large-ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { BaseIlpFailure } from "./base-ilp-failure" 2 | 3 | export class AmountTooLargeIlpFailure extends BaseIlpFailure { 4 | readonly errorCode = "F08" as const 5 | readonly name = "AmountTooLargeIlpFailure" 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/failures/internal-error-ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { BaseIlpFailure } from "./base-ilp-failure" 2 | 3 | export class InternalErrorIlpFailure extends BaseIlpFailure { 4 | readonly errorCode = "T00" as const 5 | readonly name = "InternalErrorIlpFailure" 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/failures/invalid-packet-ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { BaseIlpFailure } from "./base-ilp-failure" 2 | 3 | export class InvalidPacketIlpFailure extends BaseIlpFailure { 4 | readonly errorCode = "F01" as const 5 | readonly name = "InvalidPacketIlpFailure" 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/failures/unsupported-media-type-failure.ts: -------------------------------------------------------------------------------- 1 | import { DefaultHttpFailure } from "./default-http-failure" 2 | 3 | export class UnsupportedMediaTypeFailure extends DefaultHttpFailure { 4 | readonly name = "UnsupportedMediaTypeError" 5 | readonly statusCode = 415 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/types/http-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | import type { HttpResult } from "./http-result" 4 | 5 | export interface HttpFailure extends Failure, HttpResult { 6 | readonly statusCode: number 7 | readonly message: string 8 | } 9 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Ignore everything by default 2 | * 3 | 4 | # Includes 5 | !packages 6 | !pnpm-workspace.yaml 7 | !pnpm-lock.yaml 8 | !package.json 9 | 10 | # Excludes 11 | packages/app-website 12 | packages/*/node_modules 13 | packages/*/dist 14 | packages/*/.cache 15 | packages/*/.turbo 16 | -------------------------------------------------------------------------------- /packages/app-build/resources/systemd/dassie-update.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Run dassie-update.service once a day 3 | Documentation=https://dassie.land/ 4 | 5 | [Timer] 6 | OnCalendar=*-*-* 03:20:00 7 | RandomizedDelaySec=3600 8 | Persistent=true 9 | 10 | [Install] 11 | WantedBy=timers.target -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/failures/exceeds-debits.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export default class ExceedsDebitsFailure extends Failure { 4 | readonly name = "ExceedsDebitsFailure" 5 | } 6 | 7 | export const EXCEEDS_DEBITS_FAILURE = new ExceedsDebitsFailure() 8 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import { ManageBuiltinAccountsActor } from "./manage-builtin-accounts" 4 | 5 | export const AccountingActor = () => 6 | createActor((sig) => { 7 | sig.run(ManageBuiltinAccountsActor) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/app-dassie/src/exchange/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import { LoadExchangeRatesActor } from "./load-exchange-rates" 4 | 5 | export const ExchangeRatesActor = () => 6 | createActor(async (sig) => { 7 | await sig.run(LoadExchangeRatesActor) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/app-dev/src/constants/ports.ts: -------------------------------------------------------------------------------- 1 | export const SNI_PROXY_PORT = 443 2 | 3 | export const DEBUG_UI_PORT = 10_100 4 | export const DEBUG_UI_RPC_PORT = 10_101 5 | export const DEBUG_RUNNER_RPC_PORT = 10_102 6 | 7 | export const NODES_START_PORT = 5001 8 | export const NODES_DEBUG_START_PORT = 6001 9 | -------------------------------------------------------------------------------- /packages/lib-http-server/test/fixtures/make-headers-context.ts: -------------------------------------------------------------------------------- 1 | export function makeHeadersContext(headers: Record) { 2 | return { 3 | request: new Request("http://0.0.0.0/", { 4 | headers: new Headers({ 5 | ...headers, 6 | }), 7 | }), 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/lib-sqlite/src/types/sqlite-datatypes.ts: -------------------------------------------------------------------------------- 1 | export type SqliteDataType = "TEXT" | "INTEGER" | "REAL" | "BLOB" | "ANY" 2 | 3 | export interface SqliteToTypescriptTypeMap { 4 | TEXT: string 5 | INTEGER: bigint 6 | REAL: number 7 | BLOB: Buffer 8 | ANY: NonNullable 9 | } 10 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/src/configs/recommended.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | rules: { 3 | "@dassie/no-floating-failures": "error", 4 | "@dassie/no-misused-failures": "error", 5 | "@dassie/no-top-level-mutables": "error", 6 | "@dassie/no-top-level-side-effects": "error", 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/failures/exceeds-credits.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export default class ExceedsCreditsFailure extends Failure { 4 | readonly name = "ExceedsCreditsFailure" 5 | } 6 | 7 | export const EXCEEDS_CREDITS_FAILURE = new ExceedsCreditsFailure() 8 | -------------------------------------------------------------------------------- /packages/app-dev/src/utils/vanity-node-id-to-friendly.ts: -------------------------------------------------------------------------------- 1 | export const convertVanityNodeIdToFriendly = (vanityNodeId: string) => { 2 | const underscoreIndex = vanityNodeId.indexOf("_") 3 | return vanityNodeId.slice( 4 | 0, 5 | underscoreIndex === -1 ? undefined : underscoreIndex, 6 | ) 7 | } 8 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/assets/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /packages/lib-reactive-io/README.md: -------------------------------------------------------------------------------- 1 | # lib-reactive-io 2 | 3 | ## What is this? 4 | 5 | This is a library which can be used to abstract away runtime- or environment-specific functionality such as filesystem or network access. 6 | 7 | The goal is to make the primary code more portable and easier to test. 8 | -------------------------------------------------------------------------------- /packages/app-build/src/constants/architectures.ts: -------------------------------------------------------------------------------- 1 | export const SUPPORTED_ARCHITECTURES = [ 2 | "x64", 3 | // TODO: Re-enable ARM build once better-sqlite3 v10 binaries are available 4 | //"arm64", 5 | //"armv7l", 6 | ] as const 7 | 8 | export type Architecture = (typeof SUPPORTED_ARCHITECTURES)[number] 9 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/failures/insufficient-timeout-ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { BaseIlpFailure } from "./base-ilp-failure" 2 | 3 | export class InsufficientTimeoutIlpFailure extends BaseIlpFailure { 4 | readonly errorCode = "R02" as const 5 | readonly name = "InsufficientTimeoutIlpFailure" 6 | } 7 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/types/context.ts: -------------------------------------------------------------------------------- 1 | export interface DraftResponse { 2 | status: number | undefined 3 | statusText: string | undefined 4 | headers: Headers 5 | } 6 | 7 | export interface BaseRequestContext { 8 | url: URL 9 | request: Request 10 | response: DraftResponse 11 | } 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/failures/insufficient-liquidity-ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { BaseIlpFailure } from "./base-ilp-failure" 2 | 3 | export class InsufficientLiquidityIlpFailure extends BaseIlpFailure { 4 | readonly errorCode = "T04" as const 5 | readonly name = "InsufficientLiquidityIlpFailure" 6 | } 7 | -------------------------------------------------------------------------------- /packages/app-dassie/src/rpc-server/route-types/public.ts: -------------------------------------------------------------------------------- 1 | import { createRoute } from "@dassie/lib-rpc/server" 2 | 3 | import type { DassieActorContext } from "../../base/types/dassie-base" 4 | 5 | export const publicRoute = createRoute().context<{ 6 | sig: DassieActorContext 7 | isAuthenticated: boolean 8 | }>() 9 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/pages/payment-status/payment-status.tsx: -------------------------------------------------------------------------------- 1 | interface PaymentStatusProperties { 2 | params: { 3 | paymentId: string 4 | } 5 | } 6 | 7 | export const PaymentStatus = ({ 8 | params: { paymentId }, 9 | }: PaymentStatusProperties) => { 10 | return
{paymentId}
11 | } 12 | -------------------------------------------------------------------------------- /packages/lib-rpc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dassie/lib-rpc 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - d4606ec: Fix zod type error that occurs when using library in Vite project 8 | 9 | ## 0.0.1 10 | 11 | ### Patch Changes 12 | 13 | - Updated dependencies [6db37bc] 14 | - @dassie/lib-reactive@0.0.1 15 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/values/pending-packets-map.ts: -------------------------------------------------------------------------------- 1 | import type { PreparedIlpPacketEvent } from "../topics/prepared-ilp-packet" 2 | 3 | export type PendingPacketsKey = `${string}#${number | string}` 4 | 5 | export const PendingPacketsMap = () => 6 | new Map() 7 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/connection/failures/no-exchange-rate-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class NoExchangeRateFailure extends Failure { 4 | readonly name = "NoExchangeRateFailure" 5 | } 6 | 7 | export const NO_EXCHANGE_RATE_FAILURE = new NoExchangeRateFailure() 8 | -------------------------------------------------------------------------------- /packages/app-cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-node.json", 3 | "include": [ 4 | "index.js" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /packages/app-dassie/src/config/schemas/node-id.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod" 2 | 3 | import type { NodeId } from "../../peer-protocol/types/node-id" 4 | 5 | // TODO: Enforce valid characters 6 | export const nodeIdSchema = z 7 | .string() 8 | .min(2) 9 | .max(45) 10 | .refine((_value): _value is NodeId => true) 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/crypto/ed25519.ts: -------------------------------------------------------------------------------- 1 | import { etc } from "@noble/ed25519" 2 | 3 | import { createHash } from "node:crypto" 4 | 5 | etc.sha512Sync = (...m) => 6 | createHash("sha512") 7 | .update(etc.concatBytes(...m)) 8 | .digest() 9 | 10 | export { getPublicKey, signAsync } from "@noble/ed25519" 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/oer-schemas/peering-request-data.ts: -------------------------------------------------------------------------------- 1 | import { peeringInfoSchema } from "./peering-info-data" 2 | 3 | // Peering request data is the same as peering info data right now 4 | // eslint-disable-next-line unicorn/prefer-export-from 5 | export const peeringRequestSchema = peeringInfoSchema 6 | -------------------------------------------------------------------------------- /packages/app-dassie/src/utils/pretty-format.ts: -------------------------------------------------------------------------------- 1 | import { format } from "pretty-format" 2 | 3 | import { formatTypedArrayPlugin } from "@dassie/lib-format-utils" 4 | 5 | export const prettyFormat = (value: unknown) => 6 | format(value, { 7 | highlight: true, 8 | plugins: [formatTypedArrayPlugin], 9 | }) 10 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/connection/failures/no-remote-address-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class NoRemoteAddressFailure extends Failure { 4 | readonly name = "NoRemoteAddressFailure" 5 | } 6 | 7 | export const NO_REMOTE_ADDRESS_FAILURE = new NoRemoteAddressFailure() 8 | -------------------------------------------------------------------------------- /packages/lib-sqlite/src/types/migration.ts: -------------------------------------------------------------------------------- 1 | import type SQLite from "better-sqlite3" 2 | 3 | export interface MigrationDefinition { 4 | version: number 5 | up: (database: SQLite.Database) => void 6 | down: (database: SQLite.Database) => void 7 | } 8 | 9 | export { type default as SQLite } from "better-sqlite3" 10 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/lib/utils/create-rule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.createRule = void 0; 4 | const utils_1 = require("@typescript-eslint/utils"); 5 | exports.createRule = utils_1.ESLintUtils.RuleCreator((name) => `https://dassie.land/rule/${name}`); 6 | -------------------------------------------------------------------------------- /packages/lib-logger/src/utils/select-by-seed.ts: -------------------------------------------------------------------------------- 1 | export const selectBySeed = ( 2 | colors: readonly [T, ...T[]], 3 | seed: string, 4 | ): T => { 5 | const hash = 6 | [...seed].reduce((hash, char) => hash + (char.codePointAt(0) ?? 0), 0) % 7 | colors.length 8 | 9 | return colors[hash] ?? colors[0] 10 | } 11 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/base.json", 3 | "include": [ 4 | "**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /packages/app-build/src/steps/create-output-path.ts: -------------------------------------------------------------------------------- 1 | import { mkdir } from "node:fs/promises" 2 | 3 | import { PATH_DIST, PATH_DIST_CONTENTS } from "../constants/paths" 4 | 5 | export const createOutputPath = async () => { 6 | await mkdir(PATH_DIST, { recursive: true }) 7 | await mkdir(PATH_DIST_CONTENTS, { recursive: true }) 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/failures/invalid-link-state.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export default class InvalidLinkStateFailure extends Failure { 4 | readonly name = "InvalidLinkStateFailure" 5 | 6 | constructor(public readonly message: string) { 7 | super() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/test/topic.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test } from "vitest" 2 | 3 | import { createTopic } from ".." 4 | 5 | describe("createTopic", () => { 6 | test("should create a topic", ({ expect }) => { 7 | const topic = createTopic() 8 | expect(topic).toBeTypeOf("object") 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /packages/lib-rpc/README.md: -------------------------------------------------------------------------------- 1 | # lib-rpc 2 | 3 | This module provides a type-safe RPC layer over bi-directional sockets such as WebSockets, TCP, TLS, or Unix sockets. 4 | 5 | ## Attribution 6 | 7 | Inspired by [TRPC](https://trpc.io/). Mostly reimplemented from scratch, except where noted. Thanks and much love to the original authors. 8 | -------------------------------------------------------------------------------- /packages/meta-tsconfig/vite-node.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig.json", 3 | "display": "Vite + Node.js", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "lib": ["ES2023"], 7 | "target": "ES2022", 8 | "types": ["vite/client", "vitest/importMeta", "node"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/app-build/resources/systemd/dassie-ipc.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Dassie IPC Socket 3 | Documentation=https://dassie.land/ 4 | 5 | [Socket] 6 | ListenStream=/run/dassie.sock 7 | SocketMode=0660 8 | SocketUser=root 9 | SocketGroup=dassie-users 10 | Service=dassie.service 11 | 12 | [Install] 13 | WantedBy=sockets.target 14 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/failures/uplink-address-query.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export default class UplinkAddressQueryFailure extends Failure { 4 | readonly name = "UplinkAddressQueryFailure" 5 | 6 | constructor(public readonly message: string) { 7 | super() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/lib-format-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/trie/trie-node-already-exists-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class TrieNodeAlreadyExistsFailure extends Failure { 4 | override name = "TrieNodeAlreadyExistsFailure" 5 | } 6 | 7 | export const TRIE_NODE_ALREADY_EXISTS_FAILURE = 8 | new TrieNodeAlreadyExistsFailure() 9 | -------------------------------------------------------------------------------- /packages/lib-itergen-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/connection/failures/probing-unsuccessful-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class ProbingUnsuccessfulFailure extends Failure { 4 | readonly name = "ProbingUnsuccessfulFailure" 5 | } 6 | 7 | export const PROBING_UNSUCCESSFUL_FAILURE = new ProbingUnsuccessfulFailure() 8 | -------------------------------------------------------------------------------- /packages/lib-type-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | 9 | [*.{js,jsx,ts,tsx}] 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [*.sh] 14 | indent_style = space 15 | indent_size = 2 16 | shell_variant = posix 17 | binary_next_line = true 18 | switch_case_indent = true -------------------------------------------------------------------------------- /packages/lib-type-utils/src/is-object.ts: -------------------------------------------------------------------------------- 1 | // `keyof never` is the upper bound of all keys that can be used in indexable types, currently `string | number | symbol` 2 | // See: https://github.com/microsoft/TypeScript/issues/33025 3 | export const isObject = (o: unknown): o is Record => 4 | typeof o === "object" && o !== null 5 | -------------------------------------------------------------------------------- /packages/app-dassie/src/open-payments/schemas/wallet.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod" 2 | 3 | export const walletSchema = z.object({ 4 | id: z.string(), 5 | publicName: z.string().optional(), 6 | assetCode: z.string(), 7 | assetScale: z.number().int().min(0).max(255), 8 | authServer: z.string(), 9 | resourceServer: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/pages/debug/routing/detail/peer.tsx: -------------------------------------------------------------------------------- 1 | import type { PeerRoutingInfo } from "@dassie/app-dassie/src/routing/signals/routing-table" 2 | 3 | export const PeerRoutingDetail = ({ 4 | firstHopOptions, 5 | distance, 6 | }: PeerRoutingInfo) => { 7 | return {`${firstHopOptions.join(", ")} (distance: ${distance})`} 8 | } 9 | -------------------------------------------------------------------------------- /packages/lib-reactive-rpc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dassie/lib-reactive-rpc 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [d4606ec] 8 | - @dassie/lib-rpc@0.0.2 9 | 10 | ## 0.0.1 11 | 12 | ### Patch Changes 13 | 14 | - Updated dependencies [6db37bc] 15 | - @dassie/lib-reactive@0.0.1 16 | - @dassie/lib-rpc@0.0.1 17 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/types/factory.ts: -------------------------------------------------------------------------------- 1 | import type { Reactor } from "../reactor" 2 | 3 | export type Factory = ( 4 | reactor: Reactor, 5 | ) => TInstance 6 | 7 | export type FactoryOrInstance = 8 | | TInstance 9 | | Factory 10 | -------------------------------------------------------------------------------- /packages/lib-logger/src/types/formatter.ts: -------------------------------------------------------------------------------- 1 | import type { LogEvent } from "./log-event" 2 | 3 | export type Formatter = (value: T) => string 4 | 5 | /** 6 | * Formatters process raw log messages for a specific channel such as a terminal or browser console. 7 | * 8 | * @beta 9 | */ 10 | export type LogEventFormatter = Formatter 11 | -------------------------------------------------------------------------------- /packages/app-website/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /packages/lib-logger/src/utils/compare-level.ts: -------------------------------------------------------------------------------- 1 | import type { LogLevel } from "../types/log-level" 2 | 3 | const NUMERIC_LEVELS: Record = { 4 | debug: 0, 5 | info: 1, 6 | warn: 2, 7 | error: 3, 8 | } 9 | 10 | export function compareLogLevel(a: LogLevel, b: LogLevel) { 11 | return NUMERIC_LEVELS[a] - NUMERIC_LEVELS[b] 12 | } 13 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/server/failures/configuration-detection-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class ConfigurationDetectionFailure extends Failure { 4 | readonly name = "ConfigurationDetectionFailure" 5 | } 6 | 7 | export const CONFIGURATION_DETECTION_FAILURE = 8 | new ConfigurationDetectionFailure() 9 | -------------------------------------------------------------------------------- /packages/meta-tsconfig/vite-isomorphic.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig.json", 3 | "display": "Vite Isomorphic", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "lib": ["ES2023", "DOM", "DOM.Iterable"], 7 | "target": "ES2020", 8 | "types": ["vite/client", "vitest/importMeta"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/api-keys/database-tables/btp-tokens.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | import type { BtpToken } from "../types/btp-token" 4 | 5 | export const btpTokensTable = table({ 6 | name: "btp_tokens", 7 | columns: { 8 | token: column().type("TEXT").typescriptType().primaryKey(), 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /packages/lib-rpc/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("server/index", { 5 | external: ["zod", "@dassie/lib-type-utils"], 6 | }), 7 | ...entrypoint("client/index", { 8 | external: ["zod", "@dassie/lib-type-utils"], 9 | }), 10 | ] 11 | 12 | export default config 13 | -------------------------------------------------------------------------------- /packages/gui-dev/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react" 2 | import unocss from "unocss/vite" 3 | import { defineConfig } from "vite" 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | react(), 8 | unocss({ 9 | configFile: "./uno.config.ts", 10 | }), 11 | ], 12 | build: { 13 | target: "esnext", 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/types/nodejs-socket.ts: -------------------------------------------------------------------------------- 1 | export interface NodejsSocket { 2 | on(eventType: "data", handler: (data: string) => void): void 3 | on(eventType: "error", handler: (error: Error) => void): void 4 | on(eventType: "close", handler: () => void): void 5 | write(data: string): void 6 | end(): void 7 | setEncoding(encoding: "utf8"): void 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-build/resources/binaries/binary-dependencies.txt: -------------------------------------------------------------------------------- 1 | https://nodejs.org/dist/v22.8.0/node-v22.8.0-linux-x64.tar.xz b6827dccd983acad09496f28a0f277218cc49302a8a7179ccbd7bf38305f5623 2 | https://github.com/WiseLibs/better-sqlite3/releases/download/v11.2.1/better-sqlite3-v11.2.1-node-v127-linux-x64.tar.gz e93df0e2d155e73c88aff0da882a638cc78d848c1c19b084b0ac5543e5f56aea 3 | -------------------------------------------------------------------------------- /packages/app-website/src/pages/tools/stream-toy.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import StreamToy from "../../components/stream-toy/stream-toy.tsx" 3 | import "@dassie/gui-dassie/src/index.css" 4 | import "@dassie/meta-unocss-config/base.css" 5 | --- 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/gui-dassie/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react" 2 | import unocss from "unocss/vite" 3 | import { defineConfig } from "vite" 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | react(), 8 | unocss({ 9 | configFile: "./uno.config.ts", 10 | }), 11 | ], 12 | build: { 13 | target: "esnext", 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/src/utils/get-file-date.ts: -------------------------------------------------------------------------------- 1 | import { stat } from "node:fs/promises" 2 | 3 | export async function getFileDate(filePath: string) { 4 | const fileInfo = await stat(filePath).then( 5 | (result) => result, 6 | () => undefined, 7 | ) 8 | 9 | if (!fileInfo) return undefined 10 | 11 | return Number(fileInfo.mtime) 12 | } 13 | -------------------------------------------------------------------------------- /packages/meta-unocss-config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-node.json", 3 | "include": [ 4 | "**/*.js", 5 | "**/*.ts", 6 | "**/*.tsx" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "dist", 10 | "paths": { 11 | "@/*": [ 12 | "./src/*" 13 | ] 14 | } 15 | }, 16 | "references": [] 17 | } 18 | -------------------------------------------------------------------------------- /packages/app-dassie/src/authentication/database-tables/sessions.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | import type { SessionToken } from "../types/session-token" 4 | 5 | export const sessionsTable = table({ 6 | name: "sessions", 7 | columns: { 8 | token: column().type("TEXT").typescriptType().primaryKey(), 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/types/execution-context.ts: -------------------------------------------------------------------------------- 1 | import type { Promisable } from "type-fest" 2 | 3 | import type { WrappedCallback } from "../internal/wrap-callback" 4 | 5 | export interface ExecutionContext { 6 | callback: Promisable>( 7 | callback: TCallback, 8 | ) => WrappedCallback 9 | } 10 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/src/utils/is-top-level.ts: -------------------------------------------------------------------------------- 1 | import { AST_NODE_TYPES, type TSESTree } from "@typescript-eslint/types" 2 | 3 | export function isTopLevel(node: TSESTree.Node) { 4 | let scope = node.parent 5 | while (scope?.type === AST_NODE_TYPES.BlockStatement) { 6 | scope = scope.parent 7 | } 8 | return scope?.type === AST_NODE_TYPES.Program 9 | } 10 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.3/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "privatePackages": { "version": false, "tag": false } 11 | } 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/exchange/signals/exchange-rates.ts: -------------------------------------------------------------------------------- 1 | import { createSignal } from "@dassie/lib-reactive" 2 | 3 | export interface ExchangeRates { 4 | readonly baseCurrency: string 5 | readonly rates: Record 6 | } 7 | export const ExchangeRatesSignal = () => 8 | createSignal({ 9 | baseCurrency: "USD", 10 | rates: {}, 11 | }) 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/signals/bootstrap-node-lists.ts: -------------------------------------------------------------------------------- 1 | import { createSignal } from "@dassie/lib-reactive" 2 | 3 | import type { NodeId } from "../types/node-id" 4 | 5 | interface NodeListEntry { 6 | entries: NodeId[] 7 | hash: Uint8Array 8 | } 9 | 10 | export const BootstrapNodeListsSignal = () => 11 | createSignal(new Map()) 12 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/examples/text.ts: -------------------------------------------------------------------------------- 1 | import { header } from "../components/header" 2 | import { text } from "../components/text" 3 | import { createFlow } from "../flow" 4 | 5 | const flow = createFlow() 6 | 7 | flow.show(header({ title: "Example: Text Input" })) 8 | 9 | await flow.interact( 10 | text({ 11 | title: "Type something...", 12 | }), 13 | ) 14 | -------------------------------------------------------------------------------- /packages/app-dassie/src/acme-certificate-manager/tables/acme-tokens.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | export const acmeTokensTable = table({ 4 | name: "acme_tokens", 5 | columns: { 6 | token: column().type("TEXT").primaryKey(), 7 | key_authorization: column().type("TEXT").notNull(), 8 | expires: column().type("TEXT"), 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/base/types/dassie-base.ts: -------------------------------------------------------------------------------- 1 | import type { ActorContext, Reactor } from "@dassie/lib-reactive" 2 | import type { Clock, Crypto } from "@dassie/lib-reactive" 3 | 4 | export interface DassieBase { 5 | clock: Clock 6 | crypto: Crypto 7 | } 8 | 9 | export type DassieReactor = Reactor 10 | export type DassieActorContext = ActorContext 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/config/schemas/settlement-scheme-id.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod" 2 | 3 | import type { SettlementSchemeId } from "../../peer-protocol/types/settlement-scheme-id" 4 | 5 | // TODO: Enforce valid characters 6 | export const settlementSchemeIdSchema = z 7 | .string() 8 | .min(2) 9 | .max(128) 10 | .refine((_value): _value is SettlementSchemeId => true) 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/utils/compare-typedarray.ts: -------------------------------------------------------------------------------- 1 | export const compareUint8Arrays = (a: Uint8Array, b: Uint8Array): boolean => { 2 | if (a.length !== b.length) { 3 | return false 4 | } 5 | 6 | for (let index = 0, length = a.length; index < length; index++) { 7 | if (a[index] !== b[index]) { 8 | return false 9 | } 10 | } 11 | 12 | return true 13 | } 14 | -------------------------------------------------------------------------------- /packages/lib-logger/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("browser", { 5 | external: ["@dassie/lib-type-utils", "@dassie/lib-reactive"], 6 | }), 7 | ...entrypoint("node", { 8 | external: ["@dassie/lib-type-utils", "@dassie/lib-reactive"], 9 | }), 10 | ] 11 | 12 | export default config 13 | -------------------------------------------------------------------------------- /packages/lib-logger/src/examples/formatting/keys.ts: -------------------------------------------------------------------------------- 1 | import { showComparison } from "./util/compare" 2 | 3 | const keysTestObject = { 4 | basic: "Basic key", 5 | 0: "Numeric key", 6 | "complex-key": "Complex key", 7 | [Symbol("symbol-key")]: "Symbol key", 8 | [Symbol.for("symbol-for-key")]: "Symbol.for key", 9 | } 10 | 11 | showComparison(keysTestObject, "Keys test") 12 | -------------------------------------------------------------------------------- /packages/lib-sqlite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-node.json", 3 | "include": [ 4 | "**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-logger" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/local-ipc-server/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { ServeLocalIpcActor } from "./actors/serve-local-ipc" 5 | 6 | export const LocalRpcServerActor = () => 7 | createActor((sig: DassieActorContext) => { 8 | sig.run(ServeLocalIpcActor) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/app-dassie/src/rpc-server/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { RegisterTrpcHttpUpgradeActor } from "./rpc-server" 5 | 6 | export const TrpcServerActor = () => 7 | createActor((sig: DassieActorContext) => { 8 | sig.run(RegisterTrpcHttpUpgradeActor) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/functions/count-lines.ts: -------------------------------------------------------------------------------- 1 | import stripAnsi from "strip-ansi" 2 | import wcwidth from "wcwidth" 3 | 4 | export const countLines = (text: string, columns: number) => { 5 | let lineCount = 0 6 | for (const line of stripAnsi(text).split("\n")) { 7 | lineCount += Math.max(1, Math.ceil(wcwidth(line) / columns)) 8 | } 9 | return lineCount 10 | } 11 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/helpers/unicode-fallback.ts: -------------------------------------------------------------------------------- 1 | import isUnicodeSupported from "is-unicode-supported" 2 | 3 | import type { UnicodeWithFallback } from "../theme" 4 | 5 | export const maybeUnicode = (value: UnicodeWithFallback) => { 6 | if (typeof value === "string") { 7 | return value 8 | } 9 | 10 | return isUnicodeSupported() ? value[0] : value[1] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Launch dev server", 6 | "type": "shell", 7 | "command": "pnpm start", 8 | "group": "none", 9 | "presentation": { 10 | "reveal": "always", 11 | "panel": "new" 12 | }, 13 | "runOptions": {}, 14 | "problemMatcher": [] 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/app-dassie/src/config/computed/has-tls.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 2 | 3 | import { DatabaseConfigStore, hasTls } from "../database-config" 4 | 5 | export const HasTlsSignal = (reactor: Reactor) => 6 | createComputed(reactor, (sig) => { 7 | const config = sig.readAndTrack(DatabaseConfigStore) 8 | return hasTls(config) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ildcp-server/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { HandleIldcpRequestsActor } from "./handle-ildcp-requests" 5 | 6 | export const IldcpServerActor = () => 7 | createActor((sig: DassieActorContext) => { 8 | sig.run(HandleIldcpRequestsActor) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/failures/base-ilp-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | import type { IlpFailure } from "../types/ilp-failure" 4 | 5 | export abstract class BaseIlpFailure extends Failure implements IlpFailure { 6 | abstract readonly errorCode: string 7 | 8 | constructor(readonly message: string) { 9 | super() 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/rpc-server/route-types/protected.ts: -------------------------------------------------------------------------------- 1 | import { RpcFailure } from "@dassie/lib-rpc/server" 2 | 3 | import { publicRoute } from "./public" 4 | 5 | export const protectedRoute = publicRoute.use( 6 | ({ context: { isAuthenticated } }) => { 7 | if (!isAuthenticated) { 8 | return new RpcFailure("Unauthorized") 9 | } 10 | 11 | return 12 | }, 13 | ) 14 | -------------------------------------------------------------------------------- /packages/lib-logger/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-type-utils" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/math/failures/amount-exceeds-maximum-receive-amount.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class AmountExceedsMaximumReceiveAmountFailure extends Failure { 4 | readonly name = "AmountExceedsMaximumReceiveAmountFailure" 5 | } 6 | 7 | export const AMOUNT_EXCEEDS_MAXIMUM_RECEIVE_AMOUNT = 8 | new AmountExceedsMaximumReceiveAmountFailure() 9 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/deferred.ts: -------------------------------------------------------------------------------- 1 | export interface Deferred extends Promise { 2 | resolve(this: void, value: T): void 3 | } 4 | 5 | export const createDeferred = (): Deferred => { 6 | let resolve!: (value: T) => void 7 | const promise = new Promise((_resolve) => { 8 | resolve = _resolve 9 | }) 10 | return Object.assign(promise, { resolve }) 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "typescript.preferences.importModuleSpecifier": "project-relative", 4 | "typescript.preferences.importModuleSpecifierEnding": "minimal", 5 | "typescript.preferences.preferTypeOnlyAutoImports": true, 6 | "typescript.format.semicolons": "remove", 7 | "cSpell.words": ["Dassie", "Interledger", "Tigerbeetle"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/failures/invalid-account.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export default class InvalidAccountFailure extends Failure { 4 | readonly name = "InvalidAccountFailure" 5 | 6 | constructor( 7 | public readonly whichAccount: "debit" | "credit", 8 | public readonly accountPath: string, 9 | ) { 10 | super() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/btp-server/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { RegisterBtpHttpUpgradeActor } from "./register-btp-http-upgrade" 5 | 6 | export const BtpServerActor = () => 7 | createActor((sig: DassieActorContext) => { 8 | sig.run(RegisterBtpHttpUpgradeActor) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/app-dev/src/utils/transformer.ts: -------------------------------------------------------------------------------- 1 | import { allowErrorProps, registerClass } from "superjson" 2 | 3 | allowErrorProps("stack", "cause") 4 | registerClass(TypeError, { 5 | allowProps: ["message", "stack", "cause"], 6 | }) 7 | registerClass(AggregateError, { 8 | allowProps: ["errors", "message", "stack", "cause"], 9 | }) 10 | 11 | export { SuperJSON as transformer } from "superjson" 12 | -------------------------------------------------------------------------------- /packages/lib-protocol-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-oer" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib-reactive-io/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("browser/index", { 5 | external: ["@dassie/lib-type-utils", "@dassie/lib-reactive"], 6 | }), 7 | ...entrypoint("node/index", { 8 | external: ["@dassie/lib-type-utils", "@dassie/lib-reactive"], 9 | }), 10 | ] 11 | 12 | export default config 13 | -------------------------------------------------------------------------------- /packages/lib-reactive/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-type-utils" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-node.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-reactive" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/tables/registrations.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | export const registrationsTable = table({ 4 | name: "registrations", 5 | columns: { 6 | node: column().primaryKey().notNull().type("INTEGER"), 7 | registered_at: column().notNull().type("INTEGER"), 8 | renewed_at: column().notNull().type("INTEGER"), 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/utils/rpc.ts: -------------------------------------------------------------------------------- 1 | import superjson from "superjson" 2 | 3 | import type { AppRouter } from "@dassie/app-dassie/src/rpc-server/app-router" 4 | import { createRpcReact } from "@dassie/lib-reactive-rpc/client" 5 | 6 | export const { rpc, RpcProvider, useWebSocketClient } = 7 | createRpcReact() 8 | 9 | export const clientOptions = { 10 | transformer: superjson, 11 | } 12 | -------------------------------------------------------------------------------- /packages/lib-oer/test/utils/result.ts: -------------------------------------------------------------------------------- 1 | import { hexToUint8Array } from "../../src/utils/hex" 2 | 3 | export const serializedOk = (serializedData: string | Uint8Array) => 4 | typeof serializedData === "string" ? 5 | hexToUint8Array(serializedData) 6 | : serializedData 7 | 8 | export const parsedOk = (length: number, value: T) => ({ 9 | success: true, 10 | value, 11 | length, 12 | }) 13 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/components/common/actions/finalizations.ts: -------------------------------------------------------------------------------- 1 | export const submit = ( 2 | state: TState, 3 | ): TState & { state: "confirm" } => ({ 4 | ...state, 5 | state: "confirm", 6 | }) 7 | 8 | export const cancel = ( 9 | state: TState, 10 | ): TState & { state: "cancel" } => ({ 11 | ...state, 12 | state: "cancel", 13 | }) 14 | -------------------------------------------------------------------------------- /packages/app-dev/src/utils/prepare-data-directory.ts: -------------------------------------------------------------------------------- 1 | import { mkdir } from "node:fs/promises" 2 | 3 | import { checkFileStatus } from "./check-file-status" 4 | 5 | export const prepareDataDirectory = async (dataPath: string) => { 6 | const dataPathStatus = await checkFileStatus(dataPath) 7 | 8 | if (dataPathStatus === "missing") { 9 | await mkdir(dataPath, { recursive: true }) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/lib-logger/src/examples/formatting/promises.ts: -------------------------------------------------------------------------------- 1 | import { showComparison } from "./util/compare" 2 | 3 | const promises = { 4 | undef: Promise.resolve(), 5 | bool: Promise.resolve(true), 6 | null: Promise.resolve(null), 7 | unresolved: new Promise(() => { 8 | // no-op 9 | }), 10 | rejected: Promise.reject(new Error("Rejected")), 11 | } 12 | 13 | showComparison(promises, "Promises") 14 | -------------------------------------------------------------------------------- /packages/meta-tsconfig/vite-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig.json", 3 | "display": "Vite + React", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "lib": ["ES2023", "DOM", "DOM.Iterable"], 7 | "target": "ES2020", 8 | "jsx": "react-jsx", 9 | "jsxImportSource": "react", 10 | "types": ["vite/client", "vitest/importMeta"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/crypto/computed/node-public-key.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 2 | 3 | import { getPublicKey } from "../ed25519" 4 | import { NodePrivateKeySignal } from "./node-private-key" 5 | 6 | export const NodePublicKeySignal = (reactor: Reactor) => 7 | createComputed(reactor, (sig) => 8 | getPublicKey(sig.readAndTrack(NodePrivateKeySignal)), 9 | ) 10 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/signals/bootstrap-node-list-hashes.ts: -------------------------------------------------------------------------------- 1 | import { createSignal } from "@dassie/lib-reactive" 2 | 3 | import type { NodeId } from "../types/node-id" 4 | 5 | /** 6 | * This signal contains a map of node IDs of bootstrap nodes and their last known node list hash. 7 | */ 8 | export const BootstrapNodeListHashesSignal = () => 9 | createSignal(new Map()) 10 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/lib/configs/recommended.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.default = { 4 | rules: { 5 | "@dassie/no-floating-failures": "error", 6 | "@dassie/no-misused-failures": "error", 7 | "@dassie/no-top-level-mutables": "error", 8 | "@dassie/no-top-level-side-effects": "error", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/utils/is-rippled-error.ts: -------------------------------------------------------------------------------- 1 | import { RippledError } from "xrpl" 2 | 3 | import { isObject } from "@dassie/lib-type-utils" 4 | 5 | export const isRippledErrorWithId = ( 6 | error: unknown, 7 | errorId: string, 8 | ): boolean => 9 | error instanceof RippledError && 10 | isObject(error.data) && 11 | "error" in error.data && 12 | error.data["error"] === errorId 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/constants/anonymous-messages.ts: -------------------------------------------------------------------------------- 1 | import type { PeerMessage } from "../peer-schema" 2 | 3 | export const ALLOW_ANONYMOUS_USAGE: string[] = [ 4 | "peeringRequest", 5 | "linkStateRequest", 6 | "linkStateUpdate", 7 | "nodeListHashRequest", 8 | "nodeListRequest", 9 | "registration", 10 | "peeringInfoRequest", 11 | ] satisfies PeerMessage["content"]["value"]["type"][] 12 | -------------------------------------------------------------------------------- /packages/app-dev/src/runner/actors/handle-disconnect.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createActor } from "@dassie/lib-reactive" 2 | 3 | export const HandleDisconnectActor = (reactor: Reactor) => 4 | createActor(() => { 5 | process.on("disconnect", () => { 6 | reactor.dispose().catch((error: unknown) => { 7 | console.error("error while disposing reactor", { error }) 8 | }) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/src/utils/get-package-name.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from "node:fs" 2 | import path from "node:path" 3 | 4 | export function getPackageName(packagePath: string) { 5 | const packageJsonPath = path.resolve(packagePath, "package.json") 6 | const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { 7 | name: string 8 | } 9 | return packageJson.name 10 | } 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/command-line/commands/daemon/nodejs/log-to-console.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createActor } from "@dassie/lib-reactive" 2 | 3 | import { AttachLogger } from "../../../../logger/functions/attach-logger" 4 | 5 | export const LogToConsoleActor = (reactor: Reactor) => { 6 | const attachLogger = reactor.use(AttachLogger) 7 | 8 | return createActor(() => { 9 | attachLogger() 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /packages/lib-logger/src/types/log-event.ts: -------------------------------------------------------------------------------- 1 | import type { LogLevel } from "./log-level" 2 | 3 | export interface LogMessage { 4 | type: LogLevel 5 | namespace: string 6 | date: number 7 | message: string 8 | parameters: unknown[] 9 | caller: string | undefined 10 | } 11 | 12 | export interface LogClear { 13 | type: "clear" 14 | date: number 15 | } 16 | 17 | export type LogEvent = LogMessage | LogClear 18 | -------------------------------------------------------------------------------- /packages/lib-logger/src/utils/has-aggregated-errors.ts: -------------------------------------------------------------------------------- 1 | import { isError } from "@dassie/lib-type-utils" 2 | 3 | export const hasAggregatedErrors = ( 4 | error: Error, 5 | ): error is Error & { errors: Error[] } => { 6 | return ( 7 | error instanceof AggregateError || 8 | ("errors" in error && 9 | Array.isArray(error.errors) && 10 | error.errors.every((error) => isError(error))) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/config/computed/has-node-identity.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 2 | 3 | import { DatabaseConfigStore, hasNodeIdentity } from "../database-config" 4 | 5 | export const HasNodeIdentitySignal = (reactor: Reactor) => 6 | createComputed(reactor, (sig) => { 7 | const config = sig.readAndTrack(DatabaseConfigStore) 8 | return hasNodeIdentity(config) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/app-dassie/src/registration-client/constants/threshold.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Threshold before we consider ourselves to be registered. 3 | */ 4 | export const TARGET_REGISTRATION_THRESHOLD = 4 / 5 5 | 6 | /** 7 | * Threshold for considering another node to be a majority node. 8 | * 9 | * Number of bootstrap nodes that list the node must be greater than this number. 10 | */ 11 | export const MAJORITY_THRESHOLD = 1 / 2 12 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/packets/expiry.ts: -------------------------------------------------------------------------------- 1 | import { timestampToInterledgerTime } from "@dassie/lib-protocol-ilp" 2 | 3 | import type { StreamProtocolContext } from "../context/context" 4 | 5 | const DEFAULT_PACKET_TIMEOUT = 30_000 6 | 7 | export function getPacketExpiry(context: StreamProtocolContext) { 8 | return timestampToInterledgerTime( 9 | context.clock.now() + DEFAULT_PACKET_TIMEOUT, 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /packages/app-dev/src/utils/shorten-node-id.ts: -------------------------------------------------------------------------------- 1 | import { TEST_NODE_VANITY_IDS } from "../constants/vanity-nodes" 2 | 3 | export const NODE_ID_REGEX = /(d\d{1,4}_[\w-]{25,30})/ 4 | 5 | const vanityNodeIdsSet = new Set(TEST_NODE_VANITY_IDS) 6 | 7 | export function shortenNodeId(nodeId: string) { 8 | if (!vanityNodeIdsSet.has(nodeId)) { 9 | return nodeId 10 | } 11 | 12 | return nodeId.slice(0, nodeId.indexOf("_")) 13 | } 14 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/types/event-emitter.ts: -------------------------------------------------------------------------------- 1 | import type { Listener } from "@dassie/lib-reactive" 2 | 3 | export type EventEmitter> = { 4 | on( 5 | eventType: TEventType, 6 | listener: (event: TEventTypes[TEventType]) => void, 7 | ): void 8 | 9 | off(eventType: keyof TEventTypes, listener: Listener): void 10 | } 11 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./flow" 2 | export * from "./theme" 3 | export * from "./canceled" 4 | 5 | export * from "./components/confirm" 6 | export * from "./components/header" 7 | export * from "./components/note" 8 | export * from "./components/progress" 9 | export * from "./components/tasklist" 10 | export * from "./components/text" 11 | 12 | export type * from "./types/terminal-component" 13 | -------------------------------------------------------------------------------- /packages/app-dev/src/signals/security-token.ts: -------------------------------------------------------------------------------- 1 | import { randomBytes } from "node:crypto" 2 | 3 | import { createSignal } from "@dassie/lib-reactive" 4 | 5 | /** 6 | * This token is used for authenticating RPC requests from the dev frontend to the nodes. 7 | * 8 | * @returns Signal containing a random 64 character hex string. 9 | */ 10 | export const SecurityTokenSignal = () => 11 | createSignal(randomBytes(32).toString("hex")) 12 | -------------------------------------------------------------------------------- /packages/app-dev/src/types/runner-environment.ts: -------------------------------------------------------------------------------- 1 | import type { EnvironmentVariables } from "@dassie/app-dassie/src/config/types/environment-variables" 2 | 3 | export interface RunnerEnvironment extends EnvironmentVariables { 4 | readonly DASSIE_DEV_ROOT?: string 5 | readonly DASSIE_DEV_BASE?: string 6 | readonly DASSIE_DEV_ENTRY?: string 7 | readonly DASSIE_DEV_RPC_URL?: string 8 | readonly DASSIE_DEV_NODE_ID?: string 9 | } 10 | -------------------------------------------------------------------------------- /packages/lib-reactive-io/src/browser/index.ts: -------------------------------------------------------------------------------- 1 | import { createClock } from "../generic/clock" 2 | import type { Runtime } from "../types/runtime" 3 | import { createCrypto } from "./crypto" 4 | 5 | export const createRuntime = (): Runtime => { 6 | return { 7 | clock: createClock(), 8 | crypto: createCrypto(), 9 | } 10 | } 11 | 12 | export { createClock } from "../generic/clock" 13 | export { createCrypto } from "./crypto" 14 | -------------------------------------------------------------------------------- /packages/lib-reactive-io/src/node/index.ts: -------------------------------------------------------------------------------- 1 | import { createClock } from "../generic/clock" 2 | import type { Runtime } from "../types/runtime" 3 | import { createCrypto } from "./crypto" 4 | 5 | export const createRuntime = (): Runtime => { 6 | return { 7 | clock: createClock(), 8 | crypto: createCrypto(), 9 | } 10 | } 11 | 12 | export { createClock } from "../generic/clock" 13 | export { createCrypto } from "./crypto" 14 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/helpers/common-prefix-lines.ts: -------------------------------------------------------------------------------- 1 | export function commonPrefixLines(a: string, b: string) { 2 | const minLength = Math.min(a.length, b.length) 3 | let lineIndex = 0 4 | for (let index = 0; index < minLength; index++) { 5 | if (a[index] !== b[index]) { 6 | break 7 | } 8 | if (a[index] === "\n") { 9 | lineIndex = index + 1 10 | } 11 | } 12 | return lineIndex 13 | } 14 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/constants/currency.ts: -------------------------------------------------------------------------------- 1 | import type { CurrencySpecification } from "../types/currency" 2 | 3 | export const USD_SPECIFICATION: CurrencySpecification = { 4 | symbol: "$", 5 | code: "USD", 6 | displayPrecision: 2, 7 | totalPrecision: 9, 8 | } 9 | 10 | export const XRP_SPECIFICATION: CurrencySpecification = { 11 | symbol: "XRP", 12 | code: "XRP", 13 | displayPrecision: 2, 14 | totalPrecision: 9, 15 | } 16 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/pages/debug/state/signals/signal-state.tsx: -------------------------------------------------------------------------------- 1 | import { rpc } from "../../../../utils/rpc" 2 | 3 | interface SignalStateProperties { 4 | id: number 5 | } 6 | 7 | export function SignalState({ id }: SignalStateProperties) { 8 | const signalState = rpc.debug.getSignalState.useQuery(id) 9 | 10 | return ( 11 |
12 |
{signalState.data?.value ?? "Loading..."}
13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/lib-protocol-ildcp/src/test/fixtures/packets.ts: -------------------------------------------------------------------------------- 1 | import type { IldcpResponse } from "../../schema" 2 | 3 | export default { 4 | response: { 5 | packet: { 6 | address: "test.alice", 7 | assetScale: 9, 8 | assetCode: "XRP", 9 | }, 10 | buffer: "CnRlc3QuYWxpY2UJA1hSUA==", 11 | }, 12 | } satisfies Record< 13 | string, 14 | { 15 | packet: IldcpResponse 16 | buffer: string 17 | } 18 | > 19 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/computed/node-id.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 2 | 3 | import { NodePublicKeySignal } from "../../crypto/computed/node-public-key" 4 | import { calculateNodeId } from "../utils/calculate-node-id" 5 | 6 | export const NodeIdSignal = (reactor: Reactor) => 7 | createComputed(reactor, (sig) => 8 | calculateNodeId(sig.readAndTrack(NodePublicKeySignal)), 9 | ) 10 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/route-type.ts: -------------------------------------------------------------------------------- 1 | import type { RouteType } from "../server/router/route" 2 | 3 | export const VALID_ROUTE_TYPES = ["query", "mutation", "subscription"] as const 4 | 5 | export const VALID_ROUTE_VERBS = ["query", "mutate", "subscribe"] as const 6 | 7 | export const ROUTE_HANDLER_TO_TYPE_MAP: Record = { 8 | query: "query", 9 | mutate: "mutation", 10 | subscribe: "subscription", 11 | } as const 12 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@trivago/prettier-plugin-sort-imports", "prettier-plugin-astro"], 3 | "importOrder": ["^node:", "^@dassie/", "^[./]"], 4 | "importOrderSeparation": true, 5 | "importOrderSortSpecifiers": true, 6 | "semi": false, 7 | "experimentalTernaries": true, 8 | "overrides": [ 9 | { 10 | "files": "*.astro", 11 | "options": { 12 | "parser": "astro" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/app-build/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-node.json", 3 | "include": [ 4 | "**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-terminal-graphics" 17 | }, 18 | { 19 | "path": "../lib-type-utils" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/index.ts: -------------------------------------------------------------------------------- 1 | import type { SettlementSchemeModule } from "../types/settlement-scheme-module" 2 | 3 | const modules: Record< 4 | string, 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 6 | () => Promise<{ default: SettlementSchemeModule }> 7 | > = { 8 | stub: () => import("./stub"), 9 | "xrpl-testnet": () => import("./xrpl/xrpl-testnet"), 10 | } 11 | 12 | export default modules 13 | -------------------------------------------------------------------------------- /packages/app-dev/src/stores/peering-state.ts: -------------------------------------------------------------------------------- 1 | import { createStore } from "@dassie/lib-reactive" 2 | 3 | export const PeeringStateStore = () => 4 | createStore({} as Record).actions({ 5 | updateNodePeers: (nodeId: string, peers: string[]) => (state) => ({ 6 | ...state, 7 | [nodeId]: peers, 8 | }), 9 | // eslint-disable-next-line unicorn/consistent-function-scoping 10 | clear: () => () => ({}), 11 | }) 12 | -------------------------------------------------------------------------------- /packages/lib-oer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-format-utils" 17 | }, 18 | { 19 | "path": "../lib-type-utils" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("index", { 5 | external: [ 6 | "@dassie/lib-logger", 7 | "@dassie/lib-protocol-ildcp", 8 | "@dassie/lib-protocol-ilp", 9 | "@dassie/lib-type-utils", 10 | "@dassie/lib-oer", 11 | "@dassie/lib-reactive", 12 | ], 13 | }), 14 | ] 15 | 16 | export default config 17 | -------------------------------------------------------------------------------- /packages/lib-rpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-reactive" 17 | }, 18 | { 19 | "path": "../lib-type-utils" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/utils/calculate-message-hmac.ts: -------------------------------------------------------------------------------- 1 | import { createHmac } from "node:crypto" 2 | 3 | import { bufferToUint8Array } from "@dassie/lib-type-utils" 4 | 5 | export const calculateMessageHmac = ( 6 | message: Uint8Array, 7 | sharedSecret: Uint8Array, 8 | ): Uint8Array => { 9 | const hmac = createHmac("sha256", sharedSecret) 10 | 11 | hmac.update(message) 12 | 13 | return bufferToUint8Array(hmac.digest()) 14 | } 15 | -------------------------------------------------------------------------------- /packages/lib-protocol-ildcp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-oer" 17 | }, 18 | { 19 | "path": "../lib-type-utils" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/lib-protocol-ilp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-oer" 17 | }, 18 | { 19 | "path": "../lib-type-utils" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/lib-sqlite/test/utils/create-test-database.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type DatabaseInstance, 3 | type DatabaseSchema, 4 | createDatabase, 5 | } from "../../src" 6 | 7 | export const createTestDatabase = ( 8 | schema: TSchema, 9 | ): DatabaseInstance<{ 10 | schema: TSchema 11 | }> => { 12 | const database = createDatabase({ 13 | schema, 14 | path: ":memory:", 15 | }) 16 | 17 | return database 18 | } 19 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/test/fixture/failure.ts: -------------------------------------------------------------------------------- 1 | const FAILURE_UNIQUE_KEY = "dassie.failure" 2 | 3 | export abstract class Failure { 4 | [FAILURE_UNIQUE_KEY] = true as const 5 | abstract readonly name: string 6 | } 7 | 8 | export declare const isFailure: (value: T) => value is Extract 9 | 10 | export declare const findFailure: ( 11 | values: T, 12 | ) => { [K in keyof T]: Extract } 13 | -------------------------------------------------------------------------------- /packages/app-build/src/steps/clear-output-path.ts: -------------------------------------------------------------------------------- 1 | import { readdir, rm } from "node:fs/promises" 2 | import path from "node:path" 3 | 4 | import { PATH_DIST } from "../constants/paths" 5 | 6 | export const clearOutputPath = async () => { 7 | const files = await readdir(PATH_DIST) 8 | const deletePromises = files.map((file) => 9 | rm(path.join(PATH_DIST, file), { recursive: true, force: true }), 10 | ) 11 | await Promise.all(deletePromises) 12 | } 13 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/connection/mark-closed.ts: -------------------------------------------------------------------------------- 1 | import { closeStream } from "../stream/close" 2 | import type { ConnectionState } from "./state" 3 | 4 | export function markConnectionClosed(state: ConnectionState) { 5 | for (const [streamId, stream] of state.streams.entries()) { 6 | closeStream(streamId, state, stream) 7 | } 8 | 9 | if (!state.isClosed) { 10 | state.isClosed = true 11 | state.topics.closed.emit() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/lib-reactive-io/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-reactive" 17 | }, 18 | { 19 | "path": "../lib-type-utils" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/lib-sqlite/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create-database" 2 | export * from "./define-table" 3 | export * from "./define-column" 4 | export * from "./define-scalar" 5 | export type { MigrationDefinition } from "./types/migration" 6 | export type * from "./types/table" 7 | export type * from "./types/column" 8 | export type * from "./types/scalar" 9 | export type * from "./types/sqlite-datatypes" 10 | 11 | export { identity } from "./utils/identity" 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/authentication/signals/setup-authorization-token.ts: -------------------------------------------------------------------------------- 1 | import { uint8ArrayToHex } from "uint8array-extras" 2 | 3 | import { createSignal } from "@dassie/lib-reactive" 4 | 5 | import type { DassieReactor } from "../../base/types/dassie-base" 6 | 7 | export const SetupAuthorizationTokenSignal = (reactor: DassieReactor) => { 8 | const { crypto } = reactor.base 9 | 10 | return createSignal(uint8ArrayToHex(crypto.getRandomBytes(32))) 11 | } 12 | -------------------------------------------------------------------------------- /packages/lib-type-utils/src/bigint/gcd.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Computes the greatest common divisor (GCD) of two bigint numbers using the Euclidean algorithm. 3 | * 4 | * @param a - The first bigint. 5 | * @param b - The second bigint. 6 | * @returns The GCD of a and b. 7 | */ 8 | export function bigIntGcd(a: bigint, b: bigint): bigint { 9 | while (b !== BigInt(0)) { 10 | const previousB = b 11 | b = a % b 12 | a = previousB 13 | } 14 | return a 15 | } 16 | -------------------------------------------------------------------------------- /packages/app-dassie/src/http-server/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { RedirectToHttpsActor } from "./redirect-to-https" 5 | import { ServeFrontendActor } from "./serve-frontend" 6 | 7 | export const HttpServerActor = () => 8 | createActor((sig: DassieActorContext) => { 9 | sig.run(RedirectToHttpsActor) 10 | sig.run(ServeFrontendActor) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/pages/debug/logs/logs.tsx: -------------------------------------------------------------------------------- 1 | import { LogsStore } from "@dassie/app-dassie/src/logger/stores/logs" 2 | import { useRemoteStore } from "@dassie/lib-reactive-rpc/client" 3 | 4 | import LogViewer from "../../../components/log-viewer/log-viewer" 5 | import { rpc } from "../../../utils/rpc" 6 | 7 | export function Logs() { 8 | const { logs } = useRemoteStore(rpc.debug.subscribeToLogs, LogsStore) 9 | 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/database-tables/settlement-schemes.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | import type { SettlementSchemeId } from "../../peer-protocol/types/settlement-scheme-id" 4 | 5 | export const settlementSchemesTable = table({ 6 | name: "settlement_schemes", 7 | columns: { 8 | id: column().type("TEXT").typescriptType().primaryKey(), 9 | config: column().type("TEXT").notNull(), 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /packages/lib-logger/src/examples/formatting/getter.ts: -------------------------------------------------------------------------------- 1 | import { showComparison } from "./util/compare" 2 | 3 | const getters = { 4 | basic: { 5 | get getset() { 6 | return "Basic value" 7 | }, 8 | set getset(_value) { 9 | // no-op 10 | }, 11 | get get() { 12 | return "Getter only" 13 | }, 14 | set set(_value: string) { 15 | // no-op 16 | }, 17 | }, 18 | } 19 | 20 | showComparison(getters, "Getters and setters") 21 | -------------------------------------------------------------------------------- /packages/lib-reactive-rpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-react.json", 3 | "include": [ 4 | "src/**/*.ts", 5 | "src/**/*.tsx" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "dist", 9 | "paths": { 10 | "@/*": [ 11 | "./src/*" 12 | ] 13 | } 14 | }, 15 | "references": [ 16 | { 17 | "path": "../lib-reactive" 18 | }, 19 | { 20 | "path": "../lib-rpc" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/tables/nodes.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | import type { NodeId } from "../types/node-id" 4 | 5 | export const nodesTable = table({ 6 | name: "nodes", 7 | columns: { 8 | id: column().type("TEXT").typescriptType().primaryKey(), 9 | public_key: column().type("BLOB").notNull(), 10 | url: column().notNull().type("TEXT"), 11 | alias: column().notNull().type("TEXT"), 12 | }, 13 | }) 14 | -------------------------------------------------------------------------------- /packages/gui-dev/src/index.tsx: -------------------------------------------------------------------------------- 1 | /* @refresh reload */ 2 | import { createRoot } from "react-dom/client" 3 | import "virtual:uno.css" 4 | import "virtual:unocss-devtools" 5 | 6 | import { assertDefined } from "@dassie/lib-type-utils" 7 | import "@dassie/meta-unocss-config/base.css" 8 | 9 | import Root from "./root" 10 | 11 | const rootElement = document.querySelector("#root") 12 | assertDefined(rootElement) 13 | const root = createRoot(rootElement) 14 | root.render() 15 | -------------------------------------------------------------------------------- /packages/lib-sqlite/src/types/simplified-database.ts: -------------------------------------------------------------------------------- 1 | export interface PragmaOptions { 2 | simple?: boolean | undefined 3 | } 4 | 5 | export interface SqliteStatement { 6 | run(): void 7 | } 8 | 9 | export interface SimplifiedDatabase { 10 | memory: boolean 11 | readonly: boolean 12 | name: string 13 | open: boolean 14 | inTransaction: boolean 15 | 16 | pragma(sql: string): void 17 | prepare(sql: string): SqliteStatement 18 | exec(sql: string): void 19 | } 20 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/lib/utils/is-top-level.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.isTopLevel = isTopLevel; 4 | const types_1 = require("@typescript-eslint/types"); 5 | function isTopLevel(node) { 6 | let scope = node.parent; 7 | while (scope?.type === types_1.AST_NODE_TYPES.BlockStatement) { 8 | scope = scope.parent; 9 | } 10 | return scope?.type === types_1.AST_NODE_TYPES.Program; 11 | } 12 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-node.json", 3 | "include": [ 4 | "**/*.js", 5 | "**/*.ts" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "dist", 9 | "paths": { 10 | "@/*": [ 11 | "./src/*" 12 | ] 13 | } 14 | }, 15 | "references": [ 16 | { 17 | "path": "../lib-rpc" 18 | }, 19 | { 20 | "path": "../lib-terminal-graphics" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/app-dassie/src/logger/signals/stdout-log-level.ts: -------------------------------------------------------------------------------- 1 | import type { LogLevel } from "@dassie/lib-logger" 2 | import { type Reactor, createSignal } from "@dassie/lib-reactive" 3 | 4 | import { EnvironmentConfig } from "../../config/environment-config" 5 | 6 | export type LogLevelOption = LogLevel | "none" 7 | export const StdoutLogLevel = (reactor: Reactor) => { 8 | const { logLevel } = reactor.use(EnvironmentConfig) 9 | return createSignal(logLevel) 10 | } 11 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/utils/currency.ts: -------------------------------------------------------------------------------- 1 | export const parseDecimalToBigInt = ( 2 | amountAsDecimal: string, 3 | totalPrecision: number, 4 | ): bigint => { 5 | const [integer, decimal] = `${amountAsDecimal}.`.split(".") 6 | const integerAmount = BigInt(integer!) * BigInt(10 ** totalPrecision) 7 | const decimalAmount = 8 | decimal ? 9 | BigInt(decimal) * BigInt(10 ** (totalPrecision - decimal.length)) 10 | : 0n 11 | return integerAmount + decimalAmount 12 | } 13 | -------------------------------------------------------------------------------- /packages/gui-dev/src/components/shared/node-link/node-link.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "wouter" 2 | 3 | import { COLORS } from "@dassie/gui-dassie/src/constants/palette" 4 | import { selectBySeed } from "@dassie/lib-logger" 5 | 6 | const NodeLink = ({ id }: { id: string }) => ( 7 | 12 | {id} 13 | 14 | ) 15 | 16 | export default NodeLink 17 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/utils/cast-ledger-id.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | import { LEDGERS } from "../constants/ledgers" 4 | 5 | export function castLedgerId( 6 | id: T, 7 | ): Tagged { 8 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 9 | if (!LEDGERS[id]) { 10 | throw new Error(`Unknown ledger ID: ${id}`) 11 | } 12 | 13 | return id as Tagged 14 | } 15 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/websocket/websocket-response.ts: -------------------------------------------------------------------------------- 1 | import type { HttpResponse } from "../types/http-response" 2 | 3 | /** 4 | * WebSocket requests are upgrade requests, so this is really just a dummy value 5 | * that isn't actually used in practice. 6 | */ 7 | export class WebSocketResponse implements HttpResponse { 8 | asResponse(): Response { 9 | throw new Error( 10 | "WebSocketResponse should not be used in a non-websocket request", 11 | ) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/lib-oer/src/empty.ts: -------------------------------------------------------------------------------- 1 | import { OerType } from "./base-type" 2 | 3 | const serializer = () => { 4 | // no-op 5 | } 6 | serializer.size = 0 7 | 8 | export class OerEmpty extends OerType { 9 | clone() { 10 | return new OerEmpty() 11 | } 12 | 13 | parseWithContext() { 14 | return [undefined, 0] as const 15 | } 16 | serializeWithContext() { 17 | return serializer 18 | } 19 | } 20 | 21 | export const empty = () => { 22 | return new OerEmpty() 23 | } 24 | -------------------------------------------------------------------------------- /packages/lib-oer/test/utils/sample-strings.ts: -------------------------------------------------------------------------------- 1 | // See: https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt 2 | export const utf8TestValues = [ 3 | ["", ""], 4 | ["a", "61"], 5 | ["κόσμε", "cebae1bdb9cf83cebcceb5"], 6 | ["\u{0}", "00"], 7 | ["\u{80}", "c280"], 8 | ["\u{800}", "e0a080"], 9 | ["\u{10000}", "f0908080"], 10 | ["\u{7F}", "7f"], 11 | ["\u{7FF}", "dfbf"], 12 | ["\u{FFFF}", "efbfbf"], 13 | ["\u{10FFFF}", "f48fbfbf"], 14 | ["😄", "f09f9884"], 15 | ] 16 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/packets/parser.ts: -------------------------------------------------------------------------------- 1 | import { type StreamPacket, streamPacketSchema } from "./schema" 2 | 3 | export function deserializePacket(data: Uint8Array): StreamPacket { 4 | const result = streamPacketSchema.parseOrThrow(data) 5 | 6 | return result.value 7 | } 8 | 9 | export function serializePacket(packet: StreamPacket): Uint8Array { 10 | const serializationResult = streamPacketSchema.serializeOrThrow(packet) 11 | 12 | return serializationResult 13 | } 14 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/stream/failures/send-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class SendFailure extends Failure { 4 | readonly name = "SendFailure" 5 | 6 | constructor(readonly reason: string) { 7 | super() 8 | } 9 | } 10 | 11 | export const SEND_TIMEOUT_FAILURE = new SendFailure("Sending timed out") 12 | 13 | export const SEND_INCOMPLETE_FAILURE = new SendFailure( 14 | "Send loop exited without completing send", 15 | ) 16 | -------------------------------------------------------------------------------- /packages/app-dev/src/scenarios/index.ts: -------------------------------------------------------------------------------- 1 | import type { Scenario } from "./common" 2 | import * as crossCurrency from "./cross-currency" 3 | import * as sixNodes from "./six-nodes" 4 | import * as twoNodes from "./two-nodes" 5 | import * as xrplSettlement from "./xrpl-settlement" 6 | 7 | export const scenarios = { 8 | "two-nodes": twoNodes, 9 | "six-nodes": sixNodes, 10 | "xrpl-settlement": xrplSettlement, 11 | "cross-currency": crossCurrency, 12 | } satisfies Record 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/public-api-server/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import { RegisterNodeListMetadataHttpHandlerActor } from "./register-node-list-metadata-http-handler" 4 | import { RegisterStatisticsHttpHandlerActor } from "./register-statistics-http-handler" 5 | 6 | export const PublicApiServerActor = () => 7 | createActor((sig) => { 8 | sig.run(RegisterStatisticsHttpHandlerActor) 9 | sig.run(RegisterNodeListMetadataHttpHandlerActor) 10 | }) 11 | -------------------------------------------------------------------------------- /packages/app-dev/src/stores/additional-nodes.ts: -------------------------------------------------------------------------------- 1 | import { enableMapSet, produce } from "immer" 2 | 3 | import { createStore } from "@dassie/lib-reactive" 4 | 5 | enableMapSet() 6 | 7 | export const AdditionalNodesStore = () => 8 | createStore(new Set()).actions({ 9 | addNode: (nodeIndex: number) => 10 | produce((draft) => { 11 | draft.add(nodeIndex) 12 | }), 13 | clear: () => 14 | produce((draft) => { 15 | draft.clear() 16 | }), 17 | }) 18 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/database-tables/accounts.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | import type { AccountPath } from "../types/account-paths" 4 | 5 | export const accountsTable = table({ 6 | name: "accounts", 7 | columns: { 8 | path: column().type("TEXT").typescriptType().primaryKey(), 9 | debits_posted: column().type("INTEGER").notNull().default(0n), 10 | credits_posted: column().type("INTEGER").notNull().default(0n), 11 | }, 12 | }) 13 | -------------------------------------------------------------------------------- /packages/app-dev/src/actors/apply-debug-logging-scopes.ts: -------------------------------------------------------------------------------- 1 | import { createEnableChecker, getLogContext } from "@dassie/lib-logger" 2 | import { createActor } from "@dassie/lib-reactive" 3 | 4 | import { DebugScopesSignal } from "../signals/debug-scopes" 5 | 6 | export const ApplyDebugLoggingScopes = () => 7 | createActor((sig) => { 8 | const scopes = sig.readAndTrack(DebugScopesSignal) 9 | const context = getLogContext() 10 | context.enableChecker = createEnableChecker(scopes) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/lib-http-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-oer" 17 | }, 18 | { 19 | "path": "../lib-reactive" 20 | }, 21 | { 22 | "path": "../lib-type-utils" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/app-dev/src/scenarios/common.ts: -------------------------------------------------------------------------------- 1 | import type { AbortContext, Factory, ScopeContext } from "@dassie/lib-reactive" 2 | 3 | import type { DevelopmentBase } from "../types/development-base" 4 | 5 | export interface StartScenarioParameters { 6 | context: ScopeContext & AbortContext 7 | } 8 | 9 | export interface Scenario { 10 | name: string 11 | description: string 12 | StartScenario: Factory< 13 | (parameters: StartScenarioParameters) => Promise, 14 | DevelopmentBase 15 | > 16 | } 17 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/hooks/use-account.ts: -------------------------------------------------------------------------------- 1 | import { useState } from "react" 2 | 3 | import { USD_SPECIFICATION } from "../constants/currency" 4 | import { rpc } from "../utils/rpc" 5 | 6 | export const useAccount = () => { 7 | const [balance, setBalance] = useState(0n) 8 | 9 | rpc.general.subscribeBalance.useSubscription(undefined, { 10 | onData: (data) => { 11 | setBalance(data) 12 | }, 13 | }) 14 | 15 | return { 16 | currency: USD_SPECIFICATION, 17 | balance, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib-logger/src/examples/formatting/functions.ts: -------------------------------------------------------------------------------- 1 | import { showComparison } from "./util/compare" 2 | 3 | const functions = { 4 | func: (_foo: number, _bar: string) => { 5 | // no-op 6 | }, 7 | generator: function* () { 8 | // no-op 9 | }, 10 | asyncfun: async function () { 11 | // no-op 12 | }, 13 | named: function myname() { 14 | // no-op 15 | }, 16 | anonymous: ( 17 | () => () => 18 | void 0 19 | )(), 20 | } 21 | 22 | showComparison(functions, "Functions") 23 | -------------------------------------------------------------------------------- /packages/lib-logger/src/utils/assert.ts: -------------------------------------------------------------------------------- 1 | import type { Logger } from "../logger" 2 | 3 | export class AssertionError extends Error { 4 | constructor(message: string) { 5 | super(message) 6 | this.name = "AssertionError" 7 | } 8 | } 9 | 10 | export function assert( 11 | logger: Logger, 12 | condition: boolean, 13 | message: string, 14 | ): asserts condition { 15 | if (!condition) { 16 | logger.error(`unmet assertion: ${message}`) 17 | throw new AssertionError(message) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/stream/close.ts: -------------------------------------------------------------------------------- 1 | import type { ConnectionState } from "../connection/state" 2 | import type { StreamState } from "./state" 3 | 4 | export function closeStream( 5 | streamId: number, 6 | connectionState: ConnectionState, 7 | stream: StreamState, 8 | ) { 9 | if (stream.isClosed) return 10 | 11 | connectionState.streams.delete(streamId) 12 | connectionState.closedStreams.set(streamId, stream) 13 | 14 | stream.isClosed = true 15 | stream.topics.closed.emit() 16 | } 17 | -------------------------------------------------------------------------------- /packages/lib-x509/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-isomorphic.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "dist", 8 | "paths": { 9 | "@/*": [ 10 | "./src/*" 11 | ] 12 | } 13 | }, 14 | "references": [ 15 | { 16 | "path": "../lib-reactive" 17 | }, 18 | { 19 | "path": "../lib-reactive-io" 20 | }, 21 | { 22 | "path": "../lib-type-utils" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/app-dassie/src/acme-certificate-manager/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { ServeTokensActor } from "./serve-tokens" 5 | import { UpdateAcmeCertificateActor } from "./update-acme-certificate" 6 | 7 | export const AcmeCertificateManagerActor = () => 8 | createActor(async (sig: DassieActorContext) => { 9 | sig.run(ServeTokensActor) 10 | await sig.run(UpdateAcmeCertificateActor) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/app-dassie/src/config/computed/ilp-allocation-scheme.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 2 | 3 | import { DatabaseConfigStore } from "../database-config" 4 | 5 | export type IlpAllocationScheme = "test" | "g" 6 | 7 | export const IlpAllocationSchemeSignal = (reactor: Reactor) => 8 | createComputed(reactor, (sig): IlpAllocationScheme => { 9 | const config = sig.readAndTrack(DatabaseConfigStore) 10 | 11 | return config.realm === "test" ? "test" : "g" 12 | }) 13 | -------------------------------------------------------------------------------- /packages/app-dev/src/computed/active-node-ids.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 2 | 3 | import { ActiveNodesStore } from "../stores/active-nodes" 4 | import { nodeIndexToFriendlyId } from "../utils/generate-node-config" 5 | 6 | export const ActiveNodeIdsComputed = (reactor: Reactor) => 7 | createComputed(reactor, (sig) => 8 | sig.readAndTrack(ActiveNodesStore, (activeNodes) => 9 | [...activeNodes].map(({ index }) => nodeIndexToFriendlyId(index)), 10 | ), 11 | ) 12 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/utils/signer.ts: -------------------------------------------------------------------------------- 1 | import { hmac } from "@noble/hashes/hmac" 2 | import { sha256 } from "@noble/hashes/sha256" 3 | 4 | import type { SeedPath } from "@dassie/app-dassie/src/constants/seed-paths" 5 | 6 | export const getPrivateSeedAtPath = ( 7 | binarySeed: Uint8Array, 8 | path: SeedPath, 9 | ) => { 10 | const pathSegments = path.split("/") 11 | 12 | let key = binarySeed 13 | for (const segment of pathSegments) { 14 | key = hmac(sha256, key, segment) 15 | } 16 | 17 | return key 18 | } 19 | -------------------------------------------------------------------------------- /packages/app-dassie/src/acme-certificate-manager/schemas/database-scalars.ts: -------------------------------------------------------------------------------- 1 | import { type NamespacedScalars, scalar } from "@dassie/lib-sqlite" 2 | 3 | /** 4 | * This defines all the scalar values that are stored in the database which will 5 | * allow us to access them in a type-safe way. 6 | */ 7 | export const ACME_DATABASE_SCALARS = { 8 | acmeAccountKey: scalar().name("acme.account_key").type("TEXT"), 9 | acmeAccountUrl: scalar().name("acme.account_url").type("TEXT"), 10 | } as const satisfies NamespacedScalars<"acme"> 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/handlers/node-list-hash-request.ts: -------------------------------------------------------------------------------- 1 | import type { Reactor } from "@dassie/lib-reactive" 2 | 3 | import { NodeListHashSignal } from "../computed/node-list-hash" 4 | import type { PeerMessageHandler } from "../functions/handle-peer-message" 5 | 6 | export const HandleNodeListHashRequest = ((reactor: Reactor) => { 7 | const nodeListHashSignal = reactor.use(NodeListHashSignal) 8 | 9 | return () => ({ hash: nodeListHashSignal.read() }) 10 | }) satisfies PeerMessageHandler<"nodeListHashRequest"> 11 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/constants/palette.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Color palette for visualizing categorical data. 3 | * 4 | * @remarks 5 | * 6 | * Based on Adobe's Spectrum design system. 7 | * 8 | * @see https://spectrum.adobe.com/page/color-for-data-visualization/#Options 9 | */ 10 | export const COLORS = [ 11 | "#0fb5ae", 12 | "#4046ca", 13 | "#f68511", 14 | "#de3d82", 15 | "#7e84fa", 16 | "#72e06a", 17 | "#147af3", 18 | "#9a4dff", 19 | "#e8c600", 20 | "#cb5d00", 21 | "#008f5d", 22 | "#bce931", 23 | ] as const 24 | -------------------------------------------------------------------------------- /packages/lib-protocol-ilp/src/io.ts: -------------------------------------------------------------------------------- 1 | import type { IlpPacket, IlpPreparePacket, IlpType } from "./schema" 2 | 3 | export type IlpPacketHandler = ( 4 | packet: IlpPreparePacket, 5 | ) => Promise< 6 | IlpPacket & { type: typeof IlpType.Fulfill | typeof IlpType.Reject } 7 | > 8 | 9 | /** 10 | * A standard way of expressing a two-way Interledger communication channel. 11 | */ 12 | export type IlpEndpoint = { 13 | readonly sendPacket: IlpPacketHandler 14 | readonly handlePackets: (handler: IlpPacketHandler) => () => void 15 | } 16 | -------------------------------------------------------------------------------- /packages/lib-type-utils/src/is-error-with-code.ts: -------------------------------------------------------------------------------- 1 | import { isObject } from "./is-object" 2 | 3 | interface ErrnoException extends Error { 4 | errno?: number | undefined 5 | code?: string | undefined 6 | path?: string | undefined 7 | syscall?: string | undefined 8 | } 9 | 10 | export function isErrorWithCode( 11 | error: unknown, 12 | code: string, 13 | ): error is ErrnoException { 14 | return ( 15 | isObject(error) && 16 | typeof error["code"] === "string" && 17 | error["code"] === code 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-http/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { RegisterIlpHttpCallbackHandlerActor } from "./register-ilp-http-callback-handler" 5 | import { RegisterIlpHttpHandlerActor } from "./register-ilp-http-handler" 6 | 7 | export const IlpHttpActor = () => 8 | createActor((sig: DassieActorContext) => { 9 | sig.run(RegisterIlpHttpHandlerActor) 10 | sig.run(RegisterIlpHttpCallbackHandlerActor) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/types/nodejs-messageport.ts: -------------------------------------------------------------------------------- 1 | export interface NodejsMessagePort { 2 | close(): void 3 | postMessage(message: unknown): void 4 | on(event: "message", handler: (message: unknown) => void): void 5 | on(event: "error", handler: (error: unknown) => void): void 6 | on(event: "close", handler: () => void): void 7 | off(event: "message", handler: (message: unknown) => void): void 8 | off(event: "error", handler: (error: unknown) => void): void 9 | off(event: "close", handler: () => void): void 10 | } 11 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/base.json", 3 | "include": ["src/**/*.ts"], 4 | "compilerOptions": { 5 | "module": "Node16", 6 | "moduleResolution": "Node16", 7 | "types": ["node"], 8 | "allowImportingTsExtensions": false, 9 | "noEmit": false, 10 | "noEmitOnError": false, 11 | "emitDeclarationOnly": false, 12 | "verbatimModuleSyntax": false, 13 | "rootDir": "src", 14 | "outDir": "lib", 15 | "declarationDir": "dist" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /packages/app-dassie/src/open-payments/tables/incoming-payment.ts: -------------------------------------------------------------------------------- 1 | import { type InferRow, column, table } from "@dassie/lib-sqlite" 2 | 3 | export const incomingPaymentTable = table({ 4 | name: "incoming_payment", 5 | columns: { 6 | id: column().type("TEXT").notNull().primaryKey(), 7 | ledger: column().type("TEXT").notNull(), 8 | total_amount: column().type("INTEGER").notNull(), 9 | metadata: column().type("TEXT").notNull(), 10 | }, 11 | }) 12 | 13 | export type IncomingPaymentRow = InferRow 14 | -------------------------------------------------------------------------------- /packages/gui-dev/src/components/pages/logs/logs.tsx: -------------------------------------------------------------------------------- 1 | import { DevelopmentLogViewer } from "../../development-log-viewer/development-log-viewer" 2 | 3 | const Logs = () => { 4 | return ( 5 |
6 |
7 |

Logs

8 |
9 |
10 | 11 |
12 |
13 | ) 14 | } 15 | 16 | export default Logs 17 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/context.ts: -------------------------------------------------------------------------------- 1 | import type { BaseRequestContext } from "./types/context" 2 | 3 | export function createContext(request: Request): BaseRequestContext { 4 | let url: URL | undefined 5 | const context = { 6 | get url() { 7 | if (url) return url 8 | url = new URL(request.url) 9 | return url 10 | }, 11 | request, 12 | response: { 13 | status: undefined, 14 | statusText: undefined, 15 | headers: new Headers(), 16 | }, 17 | } 18 | 19 | return context 20 | } 21 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/connection/create-stream.ts: -------------------------------------------------------------------------------- 1 | import { createInitialStreamState } from "../stream/initialize" 2 | import type { ConnectionState } from "./state" 3 | 4 | interface CreateStreamOptions { 5 | state: ConnectionState 6 | } 7 | 8 | export function createStream({ state }: CreateStreamOptions) { 9 | const streamId = state.nextStreamId 10 | state.nextStreamId += 2 11 | const streamState = createInitialStreamState() 12 | state.streams.set(streamId, streamState) 13 | return { streamState, streamId } 14 | } 15 | -------------------------------------------------------------------------------- /packages/app-build/src/cli-options/architectures.ts: -------------------------------------------------------------------------------- 1 | import type { Type } from "cmd-ts" 2 | import { z } from "zod" 3 | 4 | import { 5 | type Architecture, 6 | SUPPORTED_ARCHITECTURES, 7 | } from "../constants/architectures" 8 | 9 | const ArchitectureSchema = z.array(z.enum(SUPPORTED_ARCHITECTURES)) 10 | 11 | export const ArchitecturesParameter: Type = { 12 | from: (value) => { 13 | const result = ArchitectureSchema.parse(value.split(",")) 14 | 15 | return Promise.resolve(result) 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /packages/app-dassie/src/crypto/functions/sign-with-dassie-key.ts: -------------------------------------------------------------------------------- 1 | import { signAsync } from "@noble/ed25519" 2 | 3 | import type { Reactor } from "@dassie/lib-reactive" 4 | 5 | import { NodePrivateKeySignal } from "../computed/node-private-key" 6 | 7 | export const SignWithDassieKey = (reactor: Reactor) => { 8 | const nodePrivateKeySignal = reactor.use(NodePrivateKeySignal) 9 | 10 | function signWithDassieKey(data: Uint8Array) { 11 | return signAsync(data, nodePrivateKeySignal.read()) 12 | } 13 | 14 | return signWithDassieKey 15 | } 16 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/tables/peers.ts: -------------------------------------------------------------------------------- 1 | import { column, table } from "@dassie/lib-sqlite" 2 | 3 | import type { SettlementSchemeId } from "../types/settlement-scheme-id" 4 | 5 | export const peersTable = table({ 6 | name: "peers", 7 | columns: { 8 | node: column().primaryKey().notNull().type("INTEGER"), 9 | settlement_scheme_id: column() 10 | .type("TEXT") 11 | .typescriptType() 12 | .notNull(), 13 | settlement_scheme_state: column().type("TEXT").notNull(), 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /packages/lib-itergen-utils/src/stream-by-line.ts: -------------------------------------------------------------------------------- 1 | async function* splitByLine( 2 | chunks: AsyncIterable, 3 | ): AsyncIterable { 4 | let buffer = "" 5 | for await (const chunk of chunks) { 6 | buffer += chunk 7 | let index 8 | while ((index = buffer.indexOf("\n")) > -1) { 9 | const line = buffer.slice(0, index) 10 | yield line 11 | buffer = buffer.slice(index + 1) 12 | } 13 | } 14 | 15 | if (buffer.length > 0) { 16 | yield buffer 17 | } 18 | } 19 | 20 | export default splitByLine 21 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dassie/lib-protocol-stream 2 | 3 | ## 0.0.1 4 | 5 | ### Patch Changes 6 | 7 | - c1e4d79: Immediately stop sending when scope is disposed 8 | - b7aaabb: Export context values in test environment 9 | - b5e2bf7: Support fluctuating exchange rates in the test environment 10 | - 6a1f9bf: Add a configurable threshold for amounts that are low enough to be considered zero. 11 | - 89b13b2: Support simulated packet loss in test environment 12 | - 7a78eb9: Provide reactive balance signals in test environment. 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/handlers/node-list-request.ts: -------------------------------------------------------------------------------- 1 | import type { Reactor } from "@dassie/lib-reactive" 2 | 3 | import { SerializedNodeListSignal } from "../computed/serialized-node-list" 4 | import type { PeerMessageHandler } from "../functions/handle-peer-message" 5 | 6 | export const HandleNodeListRequest = ((reactor: Reactor) => { 7 | const serializedNodeListSignal = reactor.use(SerializedNodeListSignal) 8 | 9 | return () => ({ bytes: serializedNodeListSignal.read() }) 10 | }) satisfies PeerMessageHandler<"nodeListRequest"> 11 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/context/context.ts: -------------------------------------------------------------------------------- 1 | import type { Logger } from "@dassie/lib-logger" 2 | import type { IlpEndpoint } from "@dassie/lib-protocol-ilp" 3 | import type { Clock, Crypto, DisposableScope } from "@dassie/lib-reactive" 4 | 5 | import type { StreamPolicy } from "./policy" 6 | 7 | export interface StreamProtocolContext { 8 | readonly crypto: Crypto 9 | readonly logger: Logger 10 | readonly endpoint: IlpEndpoint 11 | readonly scope: DisposableScope 12 | readonly clock: Clock 13 | readonly policy: StreamPolicy 14 | } 15 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/types/ilp-address.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | import type { IlpAllocationScheme } from "../../config/computed/ilp-allocation-scheme" 4 | import type { NodeId } from "../../peer-protocol/types/node-id" 5 | 6 | export type IlpAddress = DassieIlpAddress | IldcpIlpAddress | IlpHttpIlpAddress 7 | 8 | export type DassieIlpAddress = `${IlpAllocationScheme}.das.${NodeId}${string}` 9 | export type IldcpIlpAddress = "peer.config" 10 | export type IlpHttpIlpAddress = Tagged 11 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/computed/node-list-hash.ts: -------------------------------------------------------------------------------- 1 | import { createHash } from "node:crypto" 2 | 3 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 4 | 5 | import { SerializedNodeListSignal } from "./serialized-node-list" 6 | 7 | export const NodeListHashSignal = (reactor: Reactor) => 8 | createComputed(reactor, (sig) => { 9 | const nodeList = sig.readAndTrack(SerializedNodeListSignal) 10 | 11 | const hash = createHash("sha256") 12 | 13 | hash.update(nodeList) 14 | 15 | return hash.digest() 16 | }) 17 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/examples/base.ts: -------------------------------------------------------------------------------- 1 | import { type ActorContext, createActor, createReactor } from ".." 2 | 3 | interface Io { 4 | read(): string 5 | } 6 | 7 | const ActorNeedingIo = () => 8 | createActor((sig: ActorContext<{ io: Io }>) => { 9 | console.info(sig.base.io.read()) 10 | }) 11 | 12 | const RootActor = () => 13 | createActor((sig) => { 14 | const io: Io = { 15 | read() { 16 | return "foo" 17 | }, 18 | } 19 | sig.withBase({ io }).run(ActorNeedingIo) 20 | }) 21 | 22 | createReactor(RootActor) 23 | -------------------------------------------------------------------------------- /packages/lib-rpc/src/common/types/websocket.ts: -------------------------------------------------------------------------------- 1 | export interface WebSocketImplementation { 2 | addEventListener( 3 | eventType: "message", 4 | handler: (event: MessageEvent) => void, 5 | ): void 6 | addEventListener(eventType: "open" | "close", handler: () => void): void 7 | send(data: string): void 8 | close(): void 9 | readyState: number 10 | } 11 | 12 | export interface MessageEvent { 13 | data: string | Uint8Array | ArrayBuffer | Buffer[] 14 | } 15 | 16 | export type WebSocketConstructor = new (url: string) => WebSocketImplementation 17 | -------------------------------------------------------------------------------- /packages/app-build/src/constants/hashes.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from "node:fs" 2 | 3 | const binaryDependenciesText = readFileSync( 4 | new URL("../../resources/binaries/binary-dependencies.txt", import.meta.url), 5 | "utf8", 6 | ) 7 | 8 | const binaryDependencies = binaryDependenciesText 9 | .split("\n") 10 | .map((line) => line.split(" ")) 11 | .filter((line) => line[0]!.startsWith("https://")) 12 | 13 | export const VERIFIED_HASHES: Record = Object.fromEntries( 14 | binaryDependencies.map(([url, hash]) => [url!, hash!]), 15 | ) 16 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0008-create-sessions-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R8_SESSIONS_TABLE = ` 4 | CREATE TABLE sessions ( 5 | token TEXT PRIMARY KEY NOT NULL 6 | ) STRICT 7 | ` 8 | 9 | const migration: MigrationDefinition = { 10 | version: 8, 11 | up: (database) => { 12 | database.prepare(CREATE_R8_SESSIONS_TABLE).run() 13 | }, 14 | down: (database) => { 15 | database.prepare(`DROP TABLE sessions`).run() 16 | }, 17 | } 18 | 19 | export default migration 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/utils/is-connection-refused-error.ts: -------------------------------------------------------------------------------- 1 | import { isError, isErrorWithCode } from "@dassie/lib-type-utils" 2 | 3 | export function isConnectionRefusedError(error: unknown): error is TypeError { 4 | return ( 5 | isError(error) && 6 | error.name === "TypeError" && 7 | isError(error.cause) && 8 | error.cause.name === "AggregateError" && 9 | "errors" in error.cause && 10 | Array.isArray(error.cause.errors) && 11 | error.cause.errors.every((cause) => isErrorWithCode(cause, "ECONNREFUSED")) 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /packages/lib-oer/test/utils/sample-buffer.ts: -------------------------------------------------------------------------------- 1 | import { createHmac } from "node:crypto" 2 | 3 | export const sampleBuffer = initializeSampleBuffer() 4 | 5 | function initializeSampleBuffer() { 6 | const buffer = new Uint8Array(1024) 7 | 8 | for (let index = 0; index < buffer.byteLength / 512; index++) { 9 | const offset = index * 64 10 | 11 | const seededPseudoRandom = createHmac("sha512", "xen-test-seed") 12 | seededPseudoRandom.update(String(index)) 13 | buffer.set(seededPseudoRandom.digest(), offset) 14 | } 15 | 16 | return buffer 17 | } 18 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/manage-builtin-accounts.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import { initializeCommonAccounts } from "./functions/manage-common-accounts" 4 | import { OwnerLedgerIdSignal } from "./signals/owner-ledger-id" 5 | import { LedgerStore } from "./stores/ledger" 6 | 7 | export const ManageBuiltinAccountsActor = () => 8 | createActor((sig) => { 9 | const ledger = sig.reactor.use(LedgerStore) 10 | const ledgerId = sig.read(OwnerLedgerIdSignal) 11 | 12 | initializeCommonAccounts(ledger, ledgerId) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/app-dassie/src/constants/object-identifiers.ts: -------------------------------------------------------------------------------- 1 | // OBJECT IDENTIFIER courtesy of https://freeoid.pythonanywhere.com/ 2 | export const dassieObjectIdentifierPrefix = "1.3.6.1.4.1.54392.5.1399" 3 | 4 | export const dassiePeerProtocolId = `${dassieObjectIdentifierPrefix}.1` 5 | export const dassiePeerSignedHelloId = `${dassiePeerProtocolId}.1` 6 | export const dassiePeerNodeInfoId = `${dassiePeerProtocolId}.2` 7 | 8 | export const dassieNodeFingerprintId = `${dassieObjectIdentifierPrefix}.2` 9 | export const dassieNodeFingerprintV1Id = `${dassieNodeFingerprintId}.1` 10 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0009-create-btp-tokens-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R9_BTP_TOKENS_TABLE = ` 4 | CREATE TABLE btp_tokens ( 5 | token TEXT PRIMARY KEY NOT NULL 6 | ) STRICT 7 | ` 8 | 9 | const migration: MigrationDefinition = { 10 | version: 9, 11 | up: (database) => { 12 | database.prepare(CREATE_R9_BTP_TOKENS_TABLE).run() 13 | }, 14 | down: (database) => { 15 | database.prepare(`DROP TABLE btp_tokens`).run() 16 | }, 17 | } 18 | 19 | export default migration 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { ManageSettlementSchemeInstancesActor } from "./manage-settlement-scheme-instances" 5 | import { SendOutgoingSettlementsActor } from "./send-outgoing-settlements" 6 | 7 | export const LedgersActor = () => 8 | createActor(async (sig: DassieActorContext) => { 9 | await Promise.all(sig.runMap(ManageSettlementSchemeInstancesActor)) 10 | 11 | sig.runMap(SendOutgoingSettlementsActor) 12 | }) 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/functions/get-ledger-id-from-path.ts: -------------------------------------------------------------------------------- 1 | import { assert } from "@dassie/lib-logger" 2 | 3 | import { accounting as logger } from "../../logger/instances" 4 | import type { LedgerId } from "../constants/ledgers" 5 | import type { AccountPath } from "../types/account-paths" 6 | 7 | export const getLedgerIdFromPath = (path: AccountPath): LedgerId => { 8 | const colonPosition = path.indexOf(":") 9 | 10 | assert(logger, colonPosition !== -1, "account paths must contain a colon") 11 | 12 | return path.slice(0, colonPosition) as LedgerId 13 | } 14 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from "react-dom/client" 2 | import "virtual:uno.css" 3 | 4 | import { assertDefined } from "@dassie/lib-type-utils" 5 | import "@dassie/meta-unocss-config/base.css" 6 | 7 | import Root from "./root" 8 | import { checkForDevelopmentSessionToken } from "./utils/development" 9 | 10 | if (import.meta.env.DEV) { 11 | await checkForDevelopmentSessionToken() 12 | } 13 | 14 | const rootElement = document.querySelector("#root") 15 | assertDefined(rootElement) 16 | const root = createRoot(rootElement) 17 | root.render() 18 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/components/text/render-value-with-cursor.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk" 2 | 3 | import { rightGrapheme } from "../../helpers/string-offsets" 4 | 5 | export const renderValueWithCursor = ( 6 | value: string, 7 | cursor: number, 8 | ): string[] => { 9 | if (cursor >= value.length) { 10 | return [value, chalk.inverse(" ")] 11 | } 12 | 13 | const cursorEnd = rightGrapheme(value, cursor) 14 | return [ 15 | value.slice(0, cursor), 16 | chalk.inverse(value.slice(cursor, cursorEnd)), 17 | value.slice(cursorEnd), 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-dev/src/types/development-base.ts: -------------------------------------------------------------------------------- 1 | import type { ViteDevServer } from "vite" 2 | import { ViteNodeServer as ViteNodeServerType } from "vite-node/server" 3 | 4 | import type { ActorContext, Reactor } from "@dassie/lib-reactive" 5 | 6 | export interface DevelopmentBase { 7 | readonly viteServer: ViteDevServer 8 | readonly viteNodeServer: ViteNodeServerType 9 | readonly restart: () => void 10 | readonly isFirst: boolean 11 | } 12 | 13 | export type DevelopmentReactor = Reactor 14 | export type DevelopmentActorContext = ActorContext 15 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/types/scope-context.ts: -------------------------------------------------------------------------------- 1 | import type { DisposableScope, Disposer, Scope } from "../scope" 2 | 3 | export interface ScopeContext { 4 | scope: Scope 5 | } 6 | 7 | export interface DisposableScopeContext { 8 | scope: DisposableScope 9 | } 10 | 11 | export interface ScopeContextShortcuts { 12 | isDisposed: boolean 13 | onCleanup: (cleanupHandler: Disposer) => void 14 | offCleanup: (cleanupHandler: Disposer) => void 15 | } 16 | 17 | export interface DisposableScopeContextShortcuts extends ScopeContextShortcuts { 18 | dispose: () => Promise 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/utils/foreground-to-background-color.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line unicorn/import-style 2 | import { 3 | type BackgroundColorName, 4 | type ForegroundColorName, 5 | backgroundColorNames, 6 | foregroundColorNames, 7 | } from "chalk" 8 | 9 | export function foregroundToBackgroundColor( 10 | foregroundColor: ForegroundColorName, 11 | ): BackgroundColorName { 12 | const index = foregroundColorNames.indexOf(foregroundColor) 13 | 14 | if (index === -1) { 15 | return "bgGray" 16 | } 17 | 18 | return backgroundColorNames[index]! 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/constants/ledgers.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | import type { CurrencyId } from "../../exchange/constants/currencies" 4 | 5 | export const LEDGERS = { 6 | "stub+usd": { 7 | currency: "USD", 8 | }, 9 | "xrpl+xrp": { 10 | currency: "XRP", 11 | }, 12 | "xrpl-testnet+xrp": { 13 | currency: "XRP", 14 | }, 15 | } as const satisfies Record 16 | 17 | export interface LedgerDefinition { 18 | currency: CurrencyId 19 | } 20 | 21 | export type LedgerId = Tagged 22 | -------------------------------------------------------------------------------- /packages/lib-logger/src/examples/formatting/errors.ts: -------------------------------------------------------------------------------- 1 | import { showComparison } from "./util/compare" 2 | 3 | const CustomError = class CustomError extends Error { 4 | constructor(message: string) { 5 | super(message) 6 | this.name = "CustomError" 7 | } 8 | } 9 | 10 | const errors = { 11 | basic: new Error("Bad thing happened"), 12 | stackless: (() => { 13 | const error = new Error("Bad thing happened") 14 | delete error.stack 15 | return error 16 | })(), 17 | custom: new CustomError("Bad thing happened"), 18 | } 19 | 20 | showComparison(errors, "Errors") 21 | -------------------------------------------------------------------------------- /packages/lib-oer/src/utils/errors.ts: -------------------------------------------------------------------------------- 1 | import { ParseFailure, SerializeFailure } from "./failures" 2 | 3 | export class ParseError extends Error { 4 | readonly data: Uint8Array 5 | readonly offset: number 6 | 7 | constructor(cause: ParseFailure) { 8 | super(cause.message) 9 | 10 | this.name = "ParseError" 11 | this.data = cause.data 12 | this.offset = cause.offset 13 | } 14 | } 15 | 16 | export class SerializeError extends Error { 17 | constructor(cause: SerializeFailure) { 18 | super(cause.message) 19 | 20 | this.name = "SerializeError" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/app-build/src/steps/generate-metadata.ts: -------------------------------------------------------------------------------- 1 | import { mkdir, writeFile } from "node:fs/promises" 2 | import path from "node:path" 3 | 4 | import { PATH_DIST_UPLOAD } from "../constants/paths" 5 | import type { DassieVersion } from "../constants/version" 6 | 7 | export const generateMetadata = async (latestVersion: DassieVersion) => { 8 | const metadataPath = path.resolve(PATH_DIST_UPLOAD, "meta") 9 | const latestFilePath = path.resolve(metadataPath, "latest") 10 | 11 | await mkdir(metadataPath, { recursive: true }) 12 | await writeFile(latestFilePath, latestVersion, "utf8") 13 | } 14 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0006-create-peers-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R6_PEERS_TABLE = ` 4 | CREATE TABLE peers ( 5 | node INTEGER PRIMARY KEY NOT NULL, 6 | settlement_scheme_id TEXT NOT NULL 7 | ) STRICT 8 | ` 9 | 10 | const migration: MigrationDefinition = { 11 | version: 6, 12 | up: (database) => { 13 | database.prepare(CREATE_R6_PEERS_TABLE).run() 14 | }, 15 | down: (database) => { 16 | database.prepare(`DROP TABLE peers`).run() 17 | }, 18 | } 19 | 20 | export default migration 21 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0010-add-settlement-state-column.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | const migration: MigrationDefinition = { 4 | version: 10, 5 | up: (database) => { 6 | database 7 | .prepare( 8 | `ALTER TABLE peers ADD COLUMN settlement_scheme_state TEXT NOT NULL DEFAULT "{}"`, 9 | ) 10 | .run() 11 | }, 12 | down: (database) => { 13 | database 14 | .prepare(`ALTER TABLE peers DROP COLUMN settlement_scheme_state`) 15 | .run() 16 | }, 17 | } 18 | 19 | export default migration 20 | -------------------------------------------------------------------------------- /packages/lib-oer/src/information-object/class.ts: -------------------------------------------------------------------------------- 1 | import type { AnyOerType } from "../base-type" 2 | 3 | export const openType = Symbol("ASN.1 Open Type") 4 | 5 | export type ClassDefinitionShape = Record 6 | 7 | export interface InformationObjectClass< 8 | TDefinition extends ClassDefinitionShape, 9 | > { 10 | _definition: TDefinition 11 | } 12 | 13 | export const defineClass = ( 14 | definition: TDefinition, 15 | ): InformationObjectClass => { 16 | return { _definition: definition } 17 | } 18 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/connection/failures/invalid-exchange-rate-failure.ts: -------------------------------------------------------------------------------- 1 | import { Failure } from "@dassie/lib-type-utils" 2 | 3 | export class InvalidExchangeRateFailure extends Failure { 4 | readonly name = "InvalidExchangeRateFailure" 5 | 6 | constructor(readonly reason: string) { 7 | super() 8 | } 9 | } 10 | 11 | export const EXCHANGE_RATE_NEGATIVE_FAILURE = new InvalidExchangeRateFailure( 12 | "Exchange rate must be non-negative", 13 | ) 14 | export const EXCHANGE_RATE_ZERO_FAILURE = new InvalidExchangeRateFailure( 15 | "Exchange rate must be non-zero", 16 | ) 17 | -------------------------------------------------------------------------------- /packages/lib-reactive-io/src/generic/clock.ts: -------------------------------------------------------------------------------- 1 | import type { Clock, TimeoutId } from "@dassie/lib-reactive" 2 | 3 | export class GenericClockImplementation implements Clock { 4 | now(): number { 5 | return Date.now() 6 | } 7 | 8 | setTimeout(callback: () => void, delay: number): TimeoutId { 9 | return setTimeout(callback, delay) as unknown as TimeoutId 10 | } 11 | 12 | clearTimeout(id: TimeoutId): void { 13 | clearTimeout(id as unknown as NodeJS.Timeout) 14 | } 15 | } 16 | 17 | export function createClock(): Clock { 18 | return new GenericClockImplementation() 19 | } 20 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/src/entry/main.ts: -------------------------------------------------------------------------------- 1 | import { command, flag, run } from "cmd-ts" 2 | 3 | import { runChecks } from "../index.ts" 4 | 5 | const cmd = command({ 6 | name: "incremental-check", 7 | description: "Perform checks on the Dassie monorepo", 8 | version: "1.0.0", 9 | args: { 10 | all: flag({ 11 | long: "all", 12 | short: "a", 13 | description: "Run all checks even if inputs have not changed", 14 | }), 15 | }, 16 | handler: async ({ all }) => { 17 | await runChecks({ all }) 18 | }, 19 | }) 20 | 21 | await run(cmd, process.argv.slice(2)) 22 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/computed/x25519-private-key.ts: -------------------------------------------------------------------------------- 1 | import { edwardsToMontgomeryPriv } from "@noble/curves/ed25519" 2 | 3 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 4 | 5 | import { NodePrivateKeySignal } from "../../crypto/computed/node-private-key" 6 | 7 | export const X25519PrivateKey = (reactor: Reactor) => { 8 | const nodePrivateKeySignal = reactor.use(NodePrivateKeySignal) 9 | return createComputed(reactor, (sig) => { 10 | const dassieKey = sig.readAndTrack(nodePrivateKeySignal) 11 | return edwardsToMontgomeryPriv(dassieKey) 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /packages/app-dassie/src/registration-client/rpc-router/registration-client.ts: -------------------------------------------------------------------------------- 1 | import { subscribeToSignal } from "@dassie/lib-reactive-rpc/server" 2 | import { createRouter } from "@dassie/lib-rpc/server" 3 | 4 | import { protectedRoute } from "../../rpc-server/route-types/protected" 5 | import { RegistrationStatusSignal } from "../computed/registration-status" 6 | 7 | export const registrationClientRouter = createRouter({ 8 | subscribeRegistrationStatus: protectedRoute.subscription( 9 | ({ context: { sig } }) => { 10 | return subscribeToSignal(sig, RegistrationStatusSignal) 11 | }, 12 | ), 13 | }) 14 | -------------------------------------------------------------------------------- /packages/app-dev/src/stores/active-nodes.ts: -------------------------------------------------------------------------------- 1 | import { castDraft, enableMapSet, produce } from "immer" 2 | 3 | import { createStore } from "@dassie/lib-reactive" 4 | 5 | import type { NodeConfig } from "../utils/generate-node-config" 6 | 7 | enableMapSet() 8 | 9 | export const ActiveNodesStore = () => 10 | createStore(new Set()).actions({ 11 | addNode: (node: NodeConfig) => 12 | produce((draft) => { 13 | draft.add(castDraft(node)) 14 | }), 15 | removeNode: (node: NodeConfig) => 16 | produce((draft) => { 17 | draft.delete(castDraft(node)) 18 | }), 19 | }) 20 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/types/base-modules/clock.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | export type TimeoutId = Tagged 4 | 5 | export interface Clock { 6 | /** 7 | * Returns the current time in milliseconds. 8 | * 9 | * This the equivalent of `Date.now()`. 10 | */ 11 | now(): number 12 | 13 | /** 14 | * Equivalent of JavaScript's native `setTimeout`. 15 | */ 16 | setTimeout(callback: () => void, delay: number): TimeoutId 17 | 18 | /** 19 | * Equivalent of JavaScript's native `clearTimeout`. 20 | */ 21 | clearTimeout(id: TimeoutId): void 22 | } 23 | -------------------------------------------------------------------------------- /packages/app-dassie/src/constants/bootstrap-nodes.ts: -------------------------------------------------------------------------------- 1 | import type { BootstrapNodesConfig } from "../config/environment-config" 2 | import type { NodeId } from "../peer-protocol/types/node-id" 3 | 4 | export const DEFAULT_BOOTSTRAP_NODES: BootstrapNodesConfig = [ 5 | { 6 | id: "dNKbwOMCw0DTToPM4tyyVASWxM4NP3MKW" as NodeId, 7 | url: "https://test1.dassie.xyz", 8 | publicKey: "QBe5HLbdYFtIpjFTIu_Lz8lkoUJ3fmAvFHfCb9CVwIM", 9 | }, 10 | { 11 | id: "dyrjUANXiJ5S6JXxwo7jdKKJjdLtK129U" as NodeId, 12 | url: "https://test2.dassie.xyz", 13 | publicKey: "tmS1PB42DEjYi-Ua4RNguhweId9YjT9Kml3uq3iZSuQ", 14 | }, 15 | ] 16 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0005-create-nodes-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R5_NODES_TABLE = ` 4 | CREATE TABLE nodes ( 5 | id TEXT NOT NULL PRIMARY KEY, 6 | public_key BLOB NOT NULL, 7 | url TEXT NOT NULL, 8 | alias TEXT NOT NULL 9 | ) STRICT 10 | ` 11 | 12 | const migration: MigrationDefinition = { 13 | version: 5, 14 | up: (database) => { 15 | database.prepare(CREATE_R5_NODES_TABLE).run() 16 | }, 17 | down: (database) => { 18 | database.prepare(`DROP TABLE nodes`).run() 19 | }, 20 | } 21 | 22 | export default migration 23 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/effect.ts: -------------------------------------------------------------------------------- 1 | import { type ComputationContext } from "./computation-context" 2 | import { createComputed } from "./computed" 3 | import type { ScopeContext } from "./types/scope-context" 4 | import type { StatefulContext } from "./types/stateful-context" 5 | 6 | export type EffectContext = 7 | ComputationContext 8 | 9 | export const createEffect = ( 10 | context: ScopeContext & StatefulContext, 11 | behavior: (sig: EffectContext) => void, 12 | ): void => { 13 | createComputed(context, behavior, { hasSideEffects: true }) 14 | } 15 | -------------------------------------------------------------------------------- /packages/meta-incremental-check/src/utils/report-status.ts: -------------------------------------------------------------------------------- 1 | import { parentPort } from "node:worker_threads" 2 | 3 | type Status = "start" | "success" | "error" 4 | export type ProgressMessage = 5 | | ["print", message: string] 6 | | ["status", packageName: string, status: Status] 7 | 8 | function postProgress(message: ProgressMessage) { 9 | parentPort!.postMessage(message) 10 | } 11 | 12 | export function printToConsole(message: string) { 13 | postProgress(["print", message]) 14 | } 15 | 16 | export function reportPackageStatus(packageName: string, status: Status) { 17 | postProgress(["status", packageName, status]) 18 | } 19 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0007-create-acme-tokens-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R7_ACME_TOKENS_TABLE = ` 4 | CREATE TABLE acme_tokens ( 5 | token TEXT PRIMARY KEY NOT NULL, 6 | key_authorization TEXT NOT NULL, 7 | expires TEXT 8 | ) STRICT 9 | ` 10 | 11 | const migration: MigrationDefinition = { 12 | version: 7, 13 | up: (database) => { 14 | database.prepare(CREATE_R7_ACME_TOKENS_TABLE).run() 15 | }, 16 | down: (database) => { 17 | database.prepare(`DROP TABLE acme_tokens`).run() 18 | }, 19 | } 20 | 21 | export default migration 22 | -------------------------------------------------------------------------------- /packages/app-dassie/src/open-payments/index.ts: -------------------------------------------------------------------------------- 1 | import { createActor } from "@dassie/lib-reactive" 2 | 3 | import type { DassieActorContext } from "../base/types/dassie-base" 4 | import { HandleIncomingPaymentsActor } from "./handle-incoming-payments" 5 | import { HandleWalletRequestsActor } from "./handle-wallet-requests" 6 | import { StreamServerServiceActor } from "./stream-server" 7 | 8 | export const OpenPaymentsServerActor = () => 9 | createActor(async (sig: DassieActorContext) => { 10 | await sig.run(StreamServerServiceActor) 11 | sig.run(HandleIncomingPaymentsActor) 12 | sig.run(HandleWalletRequestsActor) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/lib-oer/test/base-type.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test } from "vitest" 2 | 3 | import { boolean } from "../src" 4 | 5 | describe("base type", () => { 6 | describe("as a boolean", () => { 7 | const schema = boolean() 8 | 9 | test("should be an object", ({ expect }) => { 10 | expect(schema).toBeTypeOf("object") 11 | }) 12 | 13 | describe("clone", () => { 14 | test("should return a copy", ({ expect }) => { 15 | const clone = schema.clone() 16 | expect(clone).toBeTypeOf("object") 17 | expect(clone.constructor).toEqual(schema.constructor) 18 | }) 19 | }) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /packages/lib-terminal-graphics/src/components/header.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk" 2 | 3 | import type { StaticTerminalComponent } from "../types/terminal-component" 4 | 5 | export interface HeaderOptions { 6 | title: string 7 | paddingTop?: number 8 | paddingBottom?: number 9 | } 10 | 11 | export const header = ({ 12 | title, 13 | paddingTop = 1, 14 | paddingBottom = 0, 15 | }: HeaderOptions) => 16 | ({ 17 | type: "static", 18 | render: () => [ 19 | "\n".repeat(paddingTop), 20 | chalk.blue.inverse.bold(` ${title} `), 21 | "\n".repeat(1 + paddingBottom), 22 | ], 23 | }) satisfies StaticTerminalComponent 24 | -------------------------------------------------------------------------------- /packages/app-dassie/src/config/types/environment-variables.ts: -------------------------------------------------------------------------------- 1 | export interface EnvironmentVariables { 2 | readonly FORCE_COLOR?: string 3 | readonly DEBUG?: string 4 | readonly DEBUG_HIDE_DATE?: string 5 | readonly DASSIE_ROOT?: string 6 | readonly DASSIE_STATE_DIRECTORY?: string 7 | readonly STATE_DIRECTORY?: string 8 | readonly DASSIE_CACHE_DIRECTORY?: string 9 | readonly CACHE_DIRECTORY?: string 10 | readonly DASSIE_TEMPORARY_DIRECTORY?: string 11 | readonly DASSIE_IPC_SOCKET_PATH?: string 12 | readonly DASSIE_BOOTSTRAP_NODES?: string 13 | readonly DASSIE_DEV_SECURITY_TOKEN?: string 14 | readonly DASSIE_LOG_LEVEL?: string 15 | } 16 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0011-create-accounts-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R11_ACCOUNTS_TABLE = ` 4 | CREATE TABLE accounts ( 5 | path TEXT PRIMARY KEY NOT NULL, 6 | debits_posted INTEGER NOT NULL DEFAULT 0, 7 | credits_posted INTEGER NOT NULL DEFAULT 0 8 | ) STRICT 9 | ` 10 | 11 | const migration: MigrationDefinition = { 12 | version: 11, 13 | up: (database) => { 14 | database.prepare(CREATE_R11_ACCOUNTS_TABLE).run() 15 | }, 16 | down: (database) => { 17 | database.prepare(`DROP TABLE accounts`).run() 18 | }, 19 | } 20 | 21 | export default migration 22 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0013-create-registrations-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R13_REGISTRATIONS_TABLE = ` 4 | CREATE TABLE registrations ( 5 | node INTEGER PRIMARY KEY NOT NULL, 6 | registered_at INTEGER NOT NULL, 7 | renewed_at INTEGER NOT NULL 8 | ) STRICT 9 | ` 10 | 11 | const migration: MigrationDefinition = { 12 | version: 13, 13 | up: (database) => { 14 | database.prepare(CREATE_R13_REGISTRATIONS_TABLE).run() 15 | }, 16 | down: (database) => { 17 | database.prepare(`DROP TABLE registrations`).run() 18 | }, 19 | } 20 | 21 | export default migration 22 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/stores/incoming-session-keys.ts: -------------------------------------------------------------------------------- 1 | import { enableMapSet, produce } from "immer" 2 | 3 | import { createStore } from "@dassie/lib-reactive" 4 | 5 | enableMapSet() 6 | 7 | export interface IncomingSessionKeyEntry { 8 | sharedSecret: Uint8Array 9 | createdAt: Date 10 | } 11 | 12 | export const IncomingSessionKeysStore = () => 13 | createStore(new Map()).actions({ 14 | addKeyEntry: ( 15 | sessionPublicKeyBase64: string, 16 | entry: IncomingSessionKeyEntry, 17 | ) => 18 | produce((draft) => { 19 | draft.set(sessionPublicKeyBase64, entry) 20 | }), 21 | }) 22 | -------------------------------------------------------------------------------- /packages/app-dev/src/logger/instances.ts: -------------------------------------------------------------------------------- 1 | import { type Logger, createLogger } from "@dassie/lib-logger" 2 | 3 | import * as namespaces from "./namespaces" 4 | 5 | // Logger instances must be explicitly typed to avoid TypeScript error TS2775 6 | // See: https://github.com/microsoft/TypeScript/issues/36931 7 | 8 | export const children: Logger = createLogger(namespaces.LOGGER_CHILDREN) 9 | export const runner: Logger = createLogger(namespaces.LOGGER_RUNNER) 10 | export const setup: Logger = createLogger(namespaces.LOGGER_SETUP) 11 | export const server: Logger = createLogger(namespaces.LOGGER_SERVER) 12 | export const vite: Logger = createLogger(namespaces.LOGGER_VITE) 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/command-line/commands/update/download-file.ts: -------------------------------------------------------------------------------- 1 | import { createWriteStream } from "node:fs" 2 | import { Readable } from "node:stream" 3 | import { pipeline } from "node:stream/promises" 4 | 5 | export const downloadFile = async ( 6 | url: string, 7 | localDestinationPath: string, 8 | ) => { 9 | const response = await fetch(url) 10 | 11 | const writeStream = createWriteStream(localDestinationPath) 12 | 13 | if (!response.body) { 14 | throw new Error("Response body is empty") 15 | } 16 | 17 | // eslint-disable-next-line n/no-unsupported-features/node-builtins 18 | await pipeline(Readable.fromWeb(response.body), writeStream) 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/functions/manage-common-accounts.ts: -------------------------------------------------------------------------------- 1 | import type { LedgerId } from "../constants/ledgers" 2 | import type { Ledger } from "../stores/ledger" 3 | 4 | export const initializeCommonAccounts = ( 5 | ledger: Ledger, 6 | ledgerId: LedgerId, 7 | ) => { 8 | ledger.createAccount(`${ledgerId}:assets/settlement`) 9 | ledger.createAccount(`${ledgerId}:equity/owner`) 10 | ledger.createAccount(`${ledgerId}:equity/suspense`) 11 | ledger.createAccount(`${ledgerId}:revenue/fx`) 12 | ledger.createAccount(`${ledgerId}:revenue/fees`) 13 | ledger.createAccount(`${ledgerId}:expenses/fx`) 14 | ledger.createAccount(`${ledgerId}:expenses/fees`) 15 | } 16 | -------------------------------------------------------------------------------- /packages/lib-oer/src/utils/ensure-uint8array.ts: -------------------------------------------------------------------------------- 1 | export const ensureUint8Array = (input: Uint8Array | Buffer) => { 2 | // Check if the input is an instance of Buffer (Node.js environment) 3 | if (typeof Buffer !== "undefined" && Buffer.isBuffer(input)) { 4 | // Convert Buffer to Uint8Array using the buffer's underlying ArrayBuffer 5 | return new Uint8Array(input.buffer, input.byteOffset, input.byteLength) 6 | } else if (Object.prototype.toString.call(input) === "[object Uint8Array]") { 7 | // If input is already a Uint8Array, return it as-is 8 | return input 9 | } else { 10 | throw new TypeError("Input must be a Buffer or a Uint8Array") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/computed/node-ilp-address.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 2 | 3 | import { IlpAllocationSchemeSignal } from "../../config/computed/ilp-allocation-scheme" 4 | import type { DassieIlpAddress } from "../types/ilp-address" 5 | import { NodeIdSignal } from "./node-id" 6 | 7 | export const NodeIlpAddressSignal = (reactor: Reactor) => 8 | createComputed(reactor, (sig): DassieIlpAddress => { 9 | const ilpAllocationScheme = sig.readAndTrack(IlpAllocationSchemeSignal) 10 | 11 | const nodeId = sig.readAndTrack(reactor.use(NodeIdSignal)) 12 | 13 | return `${ilpAllocationScheme}.das.${nodeId}` 14 | }) 15 | -------------------------------------------------------------------------------- /packages/app-dev/src/utils/check-file-status.ts: -------------------------------------------------------------------------------- 1 | import { access, constants } from "node:fs/promises" 2 | import { isNativeError } from "node:util/types" 3 | 4 | export const checkFileStatus = async (filePath: string) => { 5 | try { 6 | await access(filePath, constants.R_OK) 7 | return "ok" 8 | } catch (error) { 9 | const code = 10 | isNativeError(error) ? (error as NodeJS.ErrnoException).code : undefined 11 | switch (code) { 12 | case "ENOENT": { 13 | return "missing" 14 | } 15 | case "EACCES": { 16 | return "unreadable" 17 | } 18 | default: { 19 | return "error" 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/lib-sqlite/src/define-table.ts: -------------------------------------------------------------------------------- 1 | import type { Simplify } from "type-fest" 2 | 3 | import type { InferTableDescription, TableOptions } from "./types/table" 4 | 5 | export const table = ( 6 | table: TOptions, 7 | ): Simplify> => 8 | // eslint-disable-next-line @typescript-eslint/no-unsafe-return 9 | ({ 10 | ...table, 11 | columns: Object.fromEntries( 12 | Object.entries(table.columns).map(([columnName, column]) => [ 13 | columnName, 14 | column.description, 15 | ]), 16 | ), 17 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 18 | }) as any 19 | -------------------------------------------------------------------------------- /packages/app-dassie/src/database/migrations/0001-create-scalar-table.ts: -------------------------------------------------------------------------------- 1 | import type { MigrationDefinition } from "@dassie/lib-sqlite" 2 | 3 | export const CREATE_R1_SCALARS_TABLE = ` 4 | CREATE TABLE scalar ( 5 | -- String key used to index the value 6 | key TEXT PRIMARY KEY, 7 | 8 | -- Value (type is managed by the application) 9 | value ANY NOT NULL 10 | ) STRICT, WITHOUT ROWID 11 | ` 12 | 13 | const migration: MigrationDefinition = { 14 | version: 1, 15 | up: (database) => { 16 | database.prepare(CREATE_R1_SCALARS_TABLE).run() 17 | }, 18 | down: (database) => { 19 | database.prepare(`DROP TABLE scalar`).run() 20 | }, 21 | } 22 | 23 | export default migration 24 | -------------------------------------------------------------------------------- /packages/app-build/src/utils/dynamic-paths.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path" 2 | 3 | import type { Architecture } from "../constants/architectures" 4 | import { PATH_DIST_CONTENTS, PATH_DIST_STAGING } from "../constants/paths" 5 | import type { DassieVersion } from "../constants/version" 6 | import { getBundleName } from "./bundle-name" 7 | 8 | export const getStagingPath = (architecture: Architecture) => 9 | path.resolve(PATH_DIST_STAGING, architecture) 10 | 11 | export const getBundlePath = ( 12 | version: DassieVersion, 13 | architecture: Architecture, 14 | ) => 15 | path.resolve( 16 | PATH_DIST_CONTENTS, 17 | getBundleName(version, architecture), 18 | "dassie", 19 | ) 20 | -------------------------------------------------------------------------------- /packages/app-dassie/src/accounting/signals/owner-ledger-id.ts: -------------------------------------------------------------------------------- 1 | import { createSignal } from "@dassie/lib-reactive" 2 | 3 | import { castLedgerId } from "../utils/cast-ledger-id" 4 | 5 | /** 6 | * Determines which internal ledger the owner accounts are on. 7 | * 8 | * @remarks 9 | * 10 | * Dassie aims for multi-currency support but in this current version, the owner accounts are only on one ledger. This 11 | * signal determines which ledger that is. 12 | * 13 | * Owner accounts are the accounts that are used when the node's owner sends or receives money or connects a client via 14 | * BTP etc. 15 | */ 16 | export const OwnerLedgerIdSignal = () => createSignal(castLedgerId("stub+usd")) 17 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/constants/schemes.ts: -------------------------------------------------------------------------------- 1 | import type { SettlementSchemeId } from "@dassie/app-dassie/src/peer-protocol/types/settlement-scheme-id" 2 | 3 | import type { CurrencySpecification } from "../types/currency" 4 | import { USD_SPECIFICATION, XRP_SPECIFICATION } from "./currency" 5 | 6 | export const SCHEME_NAME_MAP: Record = { 7 | stub: "Stub", 8 | xrpl: "XRP Ledger", 9 | "xrpl-testnet": "XRP Ledger Testnet", 10 | } 11 | 12 | export const SCHEME_CURRENCY_MAP: Record< 13 | SettlementSchemeId, 14 | CurrencySpecification 15 | > = { 16 | stub: USD_SPECIFICATION, 17 | xrpl: XRP_SPECIFICATION, 18 | "xrpl-testnet": XRP_SPECIFICATION, 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib-reactive-rpc/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { entrypoint } from "@dassie/meta-rollup-config" 2 | 3 | const config = [ 4 | ...entrypoint("server/index", { 5 | external: [ 6 | "@dassie/lib-reactive", 7 | "@dassie/lib-rpc/server", 8 | "@dassie/lib-type-utils", 9 | ], 10 | }), 11 | ...entrypoint("client/index", { 12 | external: [ 13 | "react", 14 | "react/jsx-runtime", 15 | "@dassie/lib-reactive", 16 | "@dassie/lib-rpc/client", 17 | "@dassie/lib-rpc/server", 18 | "@dassie/lib-rpc-react", 19 | "@dassie/lib-type-utils", 20 | "@tanstack/react-query", 21 | ], 22 | }), 23 | ] 24 | 25 | export default config 26 | -------------------------------------------------------------------------------- /packages/app-dassie/src/open-payments/tables/outgoing-payment.ts: -------------------------------------------------------------------------------- 1 | import { type InferRow, column, table } from "@dassie/lib-sqlite" 2 | 3 | import type { LedgerId } from "../../accounting/constants/ledgers" 4 | 5 | export const outgoingPaymentTable = table({ 6 | name: "outgoing_payment", 7 | columns: { 8 | id: column().type("TEXT").notNull().primaryKey(), 9 | destination: column().type("TEXT").notNull(), 10 | ledger: column().type("TEXT").notNull().typescriptType(), 11 | total_amount: column().type("INTEGER").notNull(), 12 | metadata: column().type("TEXT").notNull(), 13 | }, 14 | }) 15 | 16 | export type OutgoingPaymentRow = InferRow 17 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/types/currency.ts: -------------------------------------------------------------------------------- 1 | export interface CurrencySpecification { 2 | /** 3 | * Currency symbol. 4 | * 5 | * This will be used to denote the currency in the UI, next balances or amounts. 6 | * 7 | * @example "$" 8 | * @example "kn" 9 | * @example "RD$" 10 | */ 11 | symbol: string 12 | 13 | /** 14 | * ISO 4217 currency code. 15 | * 16 | * @example "USD" 17 | */ 18 | code: string 19 | 20 | /** 21 | * Number of decimal places to display. 22 | */ 23 | displayPrecision: number 24 | 25 | /** 26 | * Location of the decimal point when expressing amounts in this currency as a bigint. 27 | */ 28 | totalPrecision: number 29 | } 30 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/stores/loaded-settlement-modules.ts: -------------------------------------------------------------------------------- 1 | import { produce } from "immer" 2 | 3 | import { createStore } from "@dassie/lib-reactive" 4 | 5 | import type { SettlementSchemeId } from "../../peer-protocol/types/settlement-scheme-id" 6 | import type { SettlementSchemeModule } from "../types/settlement-scheme-module" 7 | 8 | export const LoadedSettlementModulesStore = () => 9 | createStore(new Map()).actions({ 10 | loadModule: ( 11 | settlementSchemeId: SettlementSchemeId, 12 | module: SettlementSchemeModule, 13 | ) => 14 | produce((state) => { 15 | state.set(settlementSchemeId, module) 16 | }), 17 | }) 18 | -------------------------------------------------------------------------------- /packages/gui-dassie/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dassie/meta-tsconfig/vite-react.json", 3 | "include": [ 4 | "**/*.ts", 5 | "**/*.tsx" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "dist", 9 | "paths": { 10 | "@/*": [ 11 | "./src/*" 12 | ] 13 | } 14 | }, 15 | "references": [ 16 | { 17 | "path": "../app-dassie" 18 | }, 19 | { 20 | "path": "../lib-logger" 21 | }, 22 | { 23 | "path": "../lib-reactive" 24 | }, 25 | { 26 | "path": "../lib-reactive-rpc" 27 | }, 28 | { 29 | "path": "../lib-type-utils" 30 | }, 31 | { 32 | "path": "../meta-unocss-config" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ilp-connector/topics/resolved-ilp-packet.ts: -------------------------------------------------------------------------------- 1 | import { type IlpPacket, IlpType } from "@dassie/lib-protocol-ilp" 2 | import { createTopic } from "@dassie/lib-reactive" 3 | 4 | import type { EndpointInfo } from "../functions/send-packet" 5 | import type { PreparedIlpPacketEvent } from "./prepared-ilp-packet" 6 | 7 | export interface ResolvedIlpPacketEvent { 8 | readonly prepare: PreparedIlpPacketEvent 9 | readonly serializedPacket: Uint8Array 10 | readonly parsedPacket: Exclude 11 | readonly destinationEndpointInfo: EndpointInfo 12 | } 13 | 14 | export const ResolvedIlpPacketTopic = () => 15 | createTopic() 16 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/stores/uplink-addresses.ts: -------------------------------------------------------------------------------- 1 | import { enableMapSet, produce } from "immer" 2 | 3 | import { createStore } from "@dassie/lib-reactive" 4 | 5 | import type { IlpAddress } from "../../ilp-connector/types/ilp-address" 6 | import type { NodeId } from "../types/node-id" 7 | 8 | enableMapSet() 9 | 10 | export const UplinkAddressesStore = () => 11 | createStore(new Map()).actions({ 12 | updateAddress: (peer: NodeId, newAddress: IlpAddress | undefined) => 13 | produce((draft) => { 14 | if (!newAddress) { 15 | draft.delete(peer) 16 | return 17 | } 18 | draft.set(peer, newAddress) 19 | }), 20 | }) 21 | -------------------------------------------------------------------------------- /packages/app-dassie/src/ledgers/modules/xrpl/functions/get-account-info.ts: -------------------------------------------------------------------------------- 1 | import { type AccountInfoResponse, Client } from "xrpl" 2 | 3 | import { isRippledErrorWithId } from "../utils/is-rippled-error" 4 | 5 | export const getAccountInfo = async ( 6 | client: Client, 7 | address: string, 8 | ): Promise => { 9 | try { 10 | const response = await client.request({ 11 | command: "account_info", 12 | account: address, 13 | ledger_index: "validated", 14 | }) 15 | return response 16 | } catch (error) { 17 | if (isRippledErrorWithId(error, "actNotFound")) { 18 | return false 19 | } else { 20 | throw error 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/app-dassie/src/peer-protocol/add-majority-nodes.ts: -------------------------------------------------------------------------------- 1 | import { type Reactor, createActor } from "@dassie/lib-reactive" 2 | 3 | import { MajorityNodeListSignal } from "./computed/majority-node-list" 4 | import { NodeTableStore } from "./stores/node-table" 5 | 6 | export const AddMajorityNodesActor = (reactor: Reactor) => { 7 | const nodeTableStore = reactor.use(NodeTableStore) 8 | 9 | return createActor((sig) => { 10 | const majorityNodes = sig.readAndTrack(MajorityNodeListSignal) 11 | 12 | for (const nodeId of majorityNodes) { 13 | if (nodeTableStore.read().has(nodeId)) { 14 | continue 15 | } 16 | 17 | nodeTableStore.act.addNode(nodeId) 18 | } 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /packages/app-dev/src/runner/actors/forward-logs.ts: -------------------------------------------------------------------------------- 1 | import { LogsStore } from "@dassie/app-dassie/src/logger/stores/logs" 2 | import { createActor } from "@dassie/lib-reactive" 3 | 4 | import { type RpcReactor } from "../services/rpc-client" 5 | 6 | export const ForwardLogsActor = (reactor: RpcReactor) => { 7 | const logsStore = reactor.use(LogsStore) 8 | 9 | return createActor((sig) => { 10 | sig.on(logsStore.changes, ([action, parameters]) => { 11 | if (action === "addLogLine") { 12 | void reactor.base.rpc.notifyLogLine.mutate({ 13 | ...parameters[0], 14 | node: process.env["DASSIE_DEV_NODE_ID"] ?? "unknown", 15 | }) 16 | } 17 | }) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /packages/gui-dev/src/utils/rpc.ts: -------------------------------------------------------------------------------- 1 | import superjson, { registerClass } from "superjson" 2 | 3 | import type { UiRpcRouter } from "@dassie/app-dev/src/rpc-routers/ui-rpc-router" 4 | import { 5 | type UseWebSocketClientOptions, 6 | createRpcReact, 7 | } from "@dassie/lib-reactive-rpc/client" 8 | 9 | registerClass(TypeError, { 10 | allowProps: ["message", "stack", "cause"], 11 | }) 12 | registerClass(AggregateError, { 13 | allowProps: ["errors", "message", "stack", "cause"], 14 | }) 15 | 16 | export const { rpc, RpcProvider, useWebSocketClient } = 17 | createRpcReact() 18 | 19 | export const clientOptions: UseWebSocketClientOptions["clientOptions"] = { 20 | transformer: superjson, 21 | } 22 | -------------------------------------------------------------------------------- /packages/meta-eslint-plugin/test/utils/rule-tester.ts: -------------------------------------------------------------------------------- 1 | import { RuleTester } from "@typescript-eslint/rule-tester" 2 | import { afterAll, describe, it } from "vitest" 3 | 4 | RuleTester.afterAll = afterAll 5 | RuleTester.it = it 6 | RuleTester.itOnly = it.only 7 | RuleTester.describe = describe 8 | 9 | const fixturePath = new URL("../fixture", import.meta.url).pathname 10 | 11 | export const ruleTester = new RuleTester({ 12 | languageOptions: { 13 | parserOptions: { 14 | tsconfigRootDir: fixturePath, 15 | project: "./tsconfig.json", 16 | projectService: false, 17 | errorOnTypeScriptSyntacticAndSemanticIssues: true, 18 | errorOnUnknownASTType: true, 19 | }, 20 | }, 21 | }) 22 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/pages/network/node-detail/own-node-detail.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsWithoutRef } from "react" 2 | 3 | import { combine } from "../../../utils/class-helper" 4 | import { RegistrationSettings } from "./registration/registration" 5 | 6 | export function OwnNodeDetail({ 7 | className, 8 | ...remainingProperties 9 | }: ComponentPropsWithoutRef<"div">) { 10 | return ( 11 |
15 |

Details for Your Node

16 |

Tier 1 Registration

17 | 18 |
19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /packages/lib-http-server/src/utils/get-response-from-context.ts: -------------------------------------------------------------------------------- 1 | import type { BaseRequestContext } from "../types/context" 2 | 3 | export interface ResponseOptions { 4 | headers: Headers 5 | status?: number 6 | statusText?: string 7 | } 8 | 9 | export function getResponseOptionsFromContext( 10 | context: BaseRequestContext, 11 | ): ResponseOptions { 12 | const responseInit: ResponseOptions = { 13 | headers: context.response.headers, 14 | } 15 | 16 | if (context.response.status) { 17 | responseInit.status = context.response.status 18 | } 19 | 20 | if (context.response.statusText) { 21 | responseInit.statusText = context.response.statusText 22 | } 23 | 24 | return responseInit 25 | } 26 | -------------------------------------------------------------------------------- /packages/gui-dassie/src/pages/setup/setup-info.tsx: -------------------------------------------------------------------------------- 1 | import { Settings2 } from "lucide-react" 2 | 3 | import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert" 4 | 5 | export const SetupInfoPage = () => ( 6 |
7 | 8 | 9 | Setup 10 | 11 | This Dassie node is ready for setup. Please visit the setup URL provided 12 | in your server logs or the output of the{" "} 13 |
dassie init
command. 14 |
15 |
16 |
17 | ) 18 | -------------------------------------------------------------------------------- /packages/lib-logger/src/examples/formatting/util/compare.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import { inspect } from "node:util" 3 | 4 | import { createCliFormatter } from "../../../formatters/cli-formatter" 5 | 6 | export const showComparison = (value: unknown, title: string) => { 7 | const formatter = createCliFormatter() 8 | console.log( 9 | formatter({ 10 | type: "info", 11 | namespace: "example", 12 | date: Date.now(), 13 | message: title, 14 | parameters: [{ value }], 15 | caller: undefined, 16 | }), 17 | ) 18 | 19 | console.log( 20 | "Node inspect (for comparison):\n" + 21 | inspect(value, { depth: Number.POSITIVE_INFINITY, colors: true }), 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /packages/app-dassie/src/crypto/computed/node-private-key.ts: -------------------------------------------------------------------------------- 1 | import { assert } from "@dassie/lib-logger" 2 | import { type Reactor, createComputed } from "@dassie/lib-reactive" 3 | import { parseEd25519Key } from "@dassie/lib-x509" 4 | 5 | import { 6 | DatabaseConfigStore, 7 | hasNodeIdentity, 8 | } from "../../config/database-config" 9 | import { crypto as logger } from "../../logger/instances" 10 | 11 | export const NodePrivateKeySignal = (reactor: Reactor) => 12 | createComputed(reactor, (sig) => { 13 | const config = sig.readAndTrack(DatabaseConfigStore) 14 | 15 | assert(logger, hasNodeIdentity(config), "node identity is not configured") 16 | 17 | return parseEd25519Key(config.dassieKey, "private") 18 | }) 19 | -------------------------------------------------------------------------------- /packages/app-dev/src/runner/actors/report-peering-state.ts: -------------------------------------------------------------------------------- 1 | import { PeersSignal } from "@dassie/app-dassie/src/peer-protocol/computed/peers" 2 | import { createActor } from "@dassie/lib-reactive" 3 | 4 | import { convertVanityNodeIdToFriendly } from "../../utils/vanity-node-id-to-friendly" 5 | import type { RpcReactor } from "../services/rpc-client" 6 | 7 | export const ReportPeeringStateActor = (reactor: RpcReactor) => 8 | createActor(async (sig) => { 9 | const peers = sig.readAndTrack(PeersSignal) 10 | 11 | await reactor.base.rpc.notifyPeerState.mutate({ 12 | nodeId: process.env["DASSIE_DEV_NODE_ID"] ?? "unknown", 13 | peers: [...peers].map((peer) => convertVanityNodeIdToFriendly(peer)), 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/server/generate-unique-id.ts: -------------------------------------------------------------------------------- 1 | import { uint8ArrayToBase64 } from "uint8array-extras" 2 | 3 | import type { ServerState } from "./state" 4 | 5 | const ID_LENGTH = 4 6 | 7 | export function generateUniqueId( 8 | state: Pick< 9 | ServerState, 10 | "context" | "activeCredentials" | "activeConnections" 11 | >, 12 | ) { 13 | for (;;) { 14 | const uniqueId = uint8ArrayToBase64( 15 | state.context.crypto.getRandomBytes(ID_LENGTH), 16 | { urlSafe: true }, 17 | ) 18 | 19 | if (state.activeCredentials.has(uniqueId)) { 20 | continue 21 | } 22 | if (state.activeConnections.has(uniqueId)) { 23 | continue 24 | } 25 | 26 | return uniqueId 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/lib-reactive/src/tools/abort-timeout.ts: -------------------------------------------------------------------------------- 1 | import type { Clock } from "../types/base-modules/clock" 2 | 3 | /** 4 | * Get an abort signal that will be aborted after the given delay. 5 | * 6 | * This is a replacement for `AbortSignal.timeout` with support for passing in 7 | * a clock. 8 | * 9 | * @param clock - An instance of a Clock to manage the timeout. 10 | * @param delay - The delay in milliseconds. 11 | * @returns Abort signal which aborts after the given delay. 12 | */ 13 | export function abortTimeout(clock: Clock, delay: number): AbortSignal { 14 | const controller = new AbortController() 15 | 16 | clock.setTimeout(() => { 17 | controller.abort() 18 | }, delay) 19 | 20 | return controller.signal 21 | } 22 | -------------------------------------------------------------------------------- /packages/app-dassie/src/constants/seed-paths.ts: -------------------------------------------------------------------------------- 1 | import type { Tagged } from "type-fest" 2 | 3 | export type SeedPath = Tagged 4 | 5 | /** 6 | * Node private Ed25519 key. 7 | */ 8 | export const SEED_PATH_NODE = "node" as SeedPath 9 | 10 | /** 11 | * Secret value which is used by client to prove knowledge of node private key for login purposes. 12 | */ 13 | export const SEED_PATH_NODE_LOGIN = "node/login" as SeedPath 14 | 15 | /** 16 | * Deterministic session token used for auto-login during development. 17 | */ 18 | export const SEED_PATH_DEV_SESSION = "dev/session" as SeedPath 19 | 20 | /** 21 | * Entropy for settlement methods. 22 | */ 23 | export const SEED_PATH_SETTLEMENT_MODULE = "node/settlement-module" as SeedPath 24 | -------------------------------------------------------------------------------- /packages/lib-protocol-stream/src/stream/state.ts: -------------------------------------------------------------------------------- 1 | import type { InferTopics } from "../types/infer-topics" 2 | 3 | export interface RemoteMoneyEvent { 4 | readonly receivedAmount: bigint 5 | readonly receiveMaximum: bigint 6 | } 7 | 8 | export type StreamEvents = { 9 | money: bigint 10 | moneySent: bigint 11 | remoteMoney: RemoteMoneyEvent 12 | closed: void 13 | } 14 | 15 | export interface StreamState { 16 | sendMaximum: bigint 17 | sendHoldAmount: bigint 18 | sentAmount: bigint 19 | 20 | receiveMaximum: bigint 21 | receivedAmount: bigint 22 | 23 | topics: InferTopics 24 | 25 | isClosed: boolean 26 | 27 | remoteReceivedAmount: bigint 28 | remoteReceiveMaximum: bigint 29 | isRemoteClosed: boolean 30 | } 31 | --------------------------------------------------------------------------------