From 3f057f5752caa721d7b3a17a0cbab2be26b5cf82 Mon Sep 17 00:00:00 2001 From: pg Date: Fri, 28 Aug 2026 13:30:13 +0200 Subject: [PATCH 1/5] Type headless scratch scripts --- .github/workflows/ci.yml | 9 +- .github/workflows/release-cli.yml | 16 +- .prettierignore | 1 + Makefile | 15 +- README.md | 2 +- rust/crates/truapi-host-cli/README.md | 11 +- rust/crates/truapi-host-cli/SPEC.md | 29 +- .../js/runner-types.fixture.ts | 24 + .../truapi-host-cli/js/script-types.d.ts | 5376 +++++++++++++++++ rust/crates/truapi-host-cli/js/tsconfig.json | 12 + .../truapi-host-cli/src/script_runner.rs | 123 +- scripts/bundle-truapi-dts.mjs | 82 +- scripts/e2e-cli-update.mjs | 5 + 13 files changed, 5669 insertions(+), 36 deletions(-) create mode 100644 rust/crates/truapi-host-cli/js/runner-types.fixture.ts create mode 100644 rust/crates/truapi-host-cli/js/script-types.d.ts create mode 100644 rust/crates/truapi-host-cli/js/tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db542a688..a50e9f1ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -124,11 +124,15 @@ jobs: - name: Run codegen run: ./scripts/codegen.sh - - name: Check generated Rust output is committed + - name: Check generated output is committed run: | git diff --exit-code -- \ rust/crates/truapi-server/src/generated \ - rust/crates/truapi-server/src/wasm/generated_bridge.rs + rust/crates/truapi-server/src/wasm/generated_bridge.rs \ + rust/crates/truapi-host-cli/js/script-types.d.ts + + - name: Type-check headless host scripts + run: node_modules/.bin/tsc -p rust/crates/truapi-host-cli/js/tsconfig.json - name: Check Rust/TS wire table parity run: TRUAPI_REQUIRE_GENERATED_TS=1 cargo test -p truapi-server --test wire_table_ts_parity @@ -146,6 +150,7 @@ jobs: js/packages/truapi/src/explorer/versions.ts js/packages/truapi-host/src/generated playground/test/generated + rust/crates/truapi-host-cli/js/script-types.d.ts ios-bindings: name: iOS bindings (uniffi) diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index 9cfd86085..c1b8ead6b 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -79,7 +79,9 @@ jobs: - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: runner-bundle - path: target/dist/runner.js + path: | + target/dist/runner.js + target/dist/script-types.d.ts if-no-files-found: error build: @@ -117,8 +119,8 @@ jobs: if: endsWith(matrix.target, '-musl') run: sudo apt-get update && sudo apt-get install --no-install-recommends -y musl-tools - # `make cli-dist` treats target/dist/runner.js as a file target, so - # dropping it here means the archive reuses it instead of rebuilding. + # `make cli-dist` treats the runner artifacts as file targets, so dropping + # them here means the archive reuses them instead of rebuilding. - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: runner-bundle @@ -152,9 +154,11 @@ jobs: reported="$(./target/${{ matrix.target }}/release/truapi-host --version)" [ "${reported}" = "truapi-host ${VERSION}" ] \ || { echo "::error::binary reports '${reported}'"; exit 1; } - tar -tzf "target/dist/truapi-host-${VERSION}-${{ matrix.target }}.tar.gz" \ - | grep -qx runner.js \ - || { echo "::error::archive is missing the product-script runner"; exit 1; } + contents="$(tar -tzf "target/dist/truapi-host-${VERSION}-${{ matrix.target }}.tar.gz")" + for required in runner.js script-types.d.ts; do + grep -qx "${required}" <<< "${contents}" \ + || { echo "::error::archive is missing ${required}"; exit 1; } + done - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: diff --git a/.prettierignore b/.prettierignore index 5ae3704a7..9fdf5f77e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,4 +8,5 @@ playground/next-env.d.ts playground/tsconfig.tsbuildinfo js/packages/truapi/dist/ js/packages/truapi/node_modules/ +rust/crates/truapi-host-cli/js/script-types.d.ts REVIEW_TODO*.md diff --git a/Makefile b/Makefile index e4a7687db..c75eaef3b 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,8 @@ CLI_TARGET ?= $(shell rustc -vV | sed -n 's/^host: //p' | sed 's/-linux-gnu$$/-l CLI_VERSION ?= $(shell awk -F'"' '/^version = /{print $$2; exit}' rust/crates/truapi-host-cli/Cargo.toml) CLI_ARCHIVE := truapi-host-$(CLI_VERSION)-$(CLI_TARGET).tar.gz CLI_RUNNER := $(CLI_DIST_DIR)/runner.js +CLI_SCRIPT_TYPES_SOURCE := rust/crates/truapi-host-cli/js/script-types.d.ts +CLI_SCRIPT_TYPES := $(CLI_DIST_DIR)/script-types.d.ts CLI_STAGE := $(CLI_DIST_DIR)/$(CLI_TARGET) # macOS ships shasum, most Linux images ship only sha256sum. SHA256 := $(shell command -v sha256sum >/dev/null 2>&1 && echo "sha256sum" || echo "shasum -a 256") @@ -97,15 +99,20 @@ $(CLI_RUNNER): mkdir -p $(CLI_DIST_DIR) bun build rust/crates/truapi-host-cli/js/runner.ts --target=bun --outfile $@ -cli-runner: $(CLI_RUNNER) ## Bundle the self-contained product-script runner into target/dist. +$(CLI_SCRIPT_TYPES): $(CLI_SCRIPT_TYPES_SOURCE) + mkdir -p $(CLI_DIST_DIR) + cp $< $@ + +cli-runner: $(CLI_RUNNER) $(CLI_SCRIPT_TYPES) ## Bundle the product-script runner and its self-contained types into target/dist. + node_modules/.bin/tsc -p rust/crates/truapi-host-cli/js/tsconfig.json -cli-dist: $(CLI_RUNNER) ## Package truapi-host for CLI_TARGET into target/dist in the release artifact layout. +cli-dist: $(CLI_RUNNER) $(CLI_SCRIPT_TYPES) ## Package truapi-host for CLI_TARGET into target/dist in the release artifact layout. rustup target add $(CLI_TARGET) $(CARGO) build -p truapi-host-cli --release --target $(CLI_TARGET) rm -rf $(CLI_STAGE) mkdir -p $(CLI_STAGE) - cp target/$(CLI_TARGET)/release/truapi-host $(CLI_RUNNER) $(CLI_STAGE)/ - tar -czf $(CLI_DIST_DIR)/$(CLI_ARCHIVE) -C $(CLI_STAGE) truapi-host runner.js + cp target/$(CLI_TARGET)/release/truapi-host $(CLI_RUNNER) $(CLI_SCRIPT_TYPES) $(CLI_STAGE)/ + tar -czf $(CLI_DIST_DIR)/$(CLI_ARCHIVE) -C $(CLI_STAGE) truapi-host runner.js script-types.d.ts cd $(CLI_DIST_DIR) && $(SHA256) $(CLI_ARCHIVE) > $(CLI_ARCHIVE).sha256 @echo "packaged $(CLI_DIST_DIR)/$(CLI_ARCHIVE)" diff --git a/README.md b/README.md index bfcec79d0..0d447ac73 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ The interactive playground lets you browse every method, edit request payloads, curl -fsSL https://raw.githubusercontent.com/paritytech/host-rust-core/main/scripts/truapi-host-installer.sh | bash ``` -Prebuilt for macOS on Apple silicon and Linux on x86_64 and arm64. No Rust toolchain or checkout needed, and it keeps itself up to date. See the [`truapi-host-cli` guide](rust/crates/truapi-host-cli/README.md) for the commands, the terminal UI, and product scripts. +Prebuilt for macOS on Apple silicon and Linux on x86_64 and arm64. No Rust toolchain or checkout needed, and it keeps itself up to date. Scratch scripts created by `/script` include generated editor types for the injected `truapi`, `host`, and `assert` globals without a local npm package. See the [`truapi-host-cli` guide](rust/crates/truapi-host-cli/README.md) for the commands, the terminal UI, and product scripts. ## Usage diff --git a/rust/crates/truapi-host-cli/README.md b/rust/crates/truapi-host-cli/README.md index 60e18db2c..af12e8766 100644 --- a/rust/crates/truapi-host-cli/README.md +++ b/rust/crates/truapi-host-cli/README.md @@ -52,8 +52,9 @@ moves that one link. | `TRUAPI_HOST_BIN_DIR` | Directory the `PATH` symlink goes in, default `~/.local/bin`. | Product scripts (`--script`, `/script`) work from an installed binary: the -archive ships a `runner.js` with the `@parity/truapi` client bundled in. You -still need `bun` on `PATH`, since it executes the runner and your script. +archive ships a `runner.js` with the `@parity/truapi` client bundled in and a +self-contained `script-types.d.ts` for the globals it injects. You still need +`bun` on `PATH`, since it executes the runner and your script. Product frames use a private, per-process WebSocket-over-Unix-domain-socket by default, so starting either host does not reserve a TCP port. Pass @@ -269,8 +270,10 @@ including a path previously selected with `/script `. If that file is missing or the session has no script yet, it creates a durable Bun TypeScript file under the active host state's `scripts/` directory. The dependency-free starter calls `truapi.account.getUserId()` and prints the returned user id. -Scripts opened from an npm project can import packages installed by that -project. +The generated file references an adjacent declaration bundle, so the editor +provides completion and type checking for `truapi`, `host`, and `assert` +without requiring `@parity/truapi` in a parent npm project. Scripts opened +from an npm project can still import packages installed by that project. The TUI temporarily yields the terminal to `$VISUAL`, then `$EDITOR`, or `vi` when neither is set. After the editor exits successfully, the TUI is restored and the saved script runs through the public frame endpoint. Editor diff --git a/rust/crates/truapi-host-cli/SPEC.md b/rust/crates/truapi-host-cli/SPEC.md index f354fbfe2..36b6380e1 100644 --- a/rust/crates/truapi-host-cli/SPEC.md +++ b/rust/crates/truapi-host-cli/SPEC.md @@ -167,6 +167,8 @@ release pointer, downloads the archive for the detected target ``` $XDG_DATA_HOME/truapi-host/versions//truapi-host +$XDG_DATA_HOME/truapi-host/versions//runner.js +$XDG_DATA_HOME/truapi-host/versions//script-types.d.ts $XDG_DATA_HOME/truapi-host/current -> versions/ ~/.local/bin/truapi-host -> $XDG_DATA_HOME/truapi-host/current/truapi-host ``` @@ -200,10 +202,17 @@ The runner is resolved in this order: `TRUAPI_HOST_RUNNER`, then `runner.js` next to the running binary, then `js/runner.ts` in the source checkout (compiled from `CARGO_MANIFEST_DIR`). -A release archive ships `runner.js` beside the binary, with `@parity/truapi` -bundled in, so an installed copy runs product scripts with no source tree. A -source build has no bundle and falls back to the checkout copy, whose relative -`@parity/truapi` import means it only works from a built tree. +A release archive ships `runner.js` and `script-types.d.ts` beside the binary. +The runner has `@parity/truapi` bundled in, and the declaration file contains +the matching generated client and injected-global types, so an installed copy +runs and edits product scripts with no source tree or npm package. A source +build has no runner bundle and falls back to the checkout copies, whose +relative `@parity/truapi` import means the runner only works from a built +tree. + +A `TRUAPI_HOST_RUNNER` override must provide a compatible +`script-types.d.ts` beside the selected runner when bare `/script` needs to +create an editor scratch file. `bun` is required either way, since the runner and user scripts are executed by it. @@ -777,8 +786,8 @@ These variables are runner internals, not CLI configuration inputs. - A thrown error or rejected promise is printed as `[script error] ...` and exits `1`. - Failure to open the product socket within 15 seconds exits `2`. -- Failure to locate the runner, canonicalize the script, or spawn Bun is a CLI - error. +- Failure to locate the runner or its declaration bundle, canonicalize the + script, or spawn Bun is a CLI error. The CLI emits `Script running` before Bun starts and `Script finished` or `Script failed` afterward. @@ -824,7 +833,13 @@ by a new scratch file. The default scratch file is a dependency-free Bun script that calls `truapi.account.getUserId()` and prints `user id` followed by the returned -value. It does not emit terminal styling. +value. A same-named `.d.ts` file is copied beside it from the selected runner's +`script-types.d.ts`, and the script carries a relative triple-slash reference +to that copy. Editors therefore resolve the matching generated types for +`truapi`, `host`, and `assert` without a checkout or npm package. Keeping the +declaration beside the scratch file preserves its types across session +promotion and removal of older installed binary versions. The script does not +emit terminal styling. Mnemonic-backed ephemeral signing sessions remember a path only for the current process and create scratch files under the system temporary diff --git a/rust/crates/truapi-host-cli/js/runner-types.fixture.ts b/rust/crates/truapi-host-cli/js/runner-types.fixture.ts new file mode 100644 index 000000000..6f52ab494 --- /dev/null +++ b/rust/crates/truapi-host-cli/js/runner-types.fixture.ts @@ -0,0 +1,24 @@ +/// +export {}; + +const productContext = await truapi.system.getProductContext(); +if (productContext.isOk()) { + const productId: string = productContext.value.productId; + assert(productId.length > 0); + + // @ts-expect-error Product context does not contain the signed-in user. + productContext.value.userId; +} + +const account = host.productAccount(0); +const accountProductId: string = account.dotNsIdentifier; +assert(accountProductId.length > 0); + +// @ts-expect-error Product accounts have no user-facing username. +account.username; + +// @ts-expect-error Derivation indices are numeric. +host.productAccount("0"); + +// @ts-expect-error The generated client rejects unknown services. +truapi.unknownService; diff --git a/rust/crates/truapi-host-cli/js/script-types.d.ts b/rust/crates/truapi-host-cli/js/script-types.d.ts new file mode 100644 index 000000000..e8137955c --- /dev/null +++ b/rust/crates/truapi-host-cli/js/script-types.d.ts @@ -0,0 +1,5376 @@ +// Auto-generated by scripts/bundle-truapi-dts.mjs. Do not edit. + +interface ErrorConfig { + withStackTrace: boolean; +} + +declare class ResultAsync implements PromiseLike> { + private _promise; + constructor(res: Promise>); + static fromSafePromise(promise: PromiseLike): ResultAsync; + static fromPromise(promise: PromiseLike, errorFn: (e: unknown) => E): ResultAsync; + static fromThrowable(fn: (...args: A) => Promise, errorFn?: (err: unknown) => E): (...args: A) => ResultAsync; + static combine, ...ResultAsync[]]>(asyncResultList: T): CombineResultAsyncs; + static combine[]>(asyncResultList: T): CombineResultAsyncs; + static combineWithAllErrors, ...ResultAsync[]]>(asyncResultList: T): CombineResultsWithAllErrorsArrayAsync; + static combineWithAllErrors[]>(asyncResultList: T): CombineResultsWithAllErrorsArrayAsync; + map(f: (t: T) => A | Promise): ResultAsync; + andThrough(f: (t: T) => Result | ResultAsync): ResultAsync; + andTee(f: (t: T) => unknown): ResultAsync; + orTee(f: (t: E) => unknown): ResultAsync; + mapErr(f: (e: E) => U | Promise): ResultAsync; + andThen>(f: (t: T) => R): ResultAsync, InferErrTypes | E>; + andThen>(f: (t: T) => R): ResultAsync, InferAsyncErrTypes | E>; + andThen(f: (t: T) => Result | ResultAsync): ResultAsync; + orElse>(f: (e: E) => R): ResultAsync | T, InferErrTypes>; + orElse>(f: (e: E) => R): ResultAsync | T, InferAsyncErrTypes>; + orElse(f: (e: E) => Result | ResultAsync): ResultAsync; + match(ok: (t: T) => A, _err: (e: E) => B): Promise; + unwrapOr(t: A): Promise; + /** + * @deprecated will be removed in 9.0.0. + * + * You can use `safeTry` without this method. + * @example + * ```typescript + * safeTry(async function* () { + * const okValue = yield* yourResult + * }) + * ``` + * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`. + */ + safeUnwrap(): AsyncGenerator, T>; + then(successCallback?: (res: Result) => A | PromiseLike, failureCallback?: (reason: unknown) => B | PromiseLike): PromiseLike; + [Symbol.asyncIterator](): AsyncGenerator, T>; +} +declare function okAsync(value: T): ResultAsync; +declare function okAsync(value: void): ResultAsync; +declare function errAsync(err: E): ResultAsync; +declare function errAsync(err: void): ResultAsync; +declare const fromPromise: typeof ResultAsync.fromPromise; +declare const fromSafePromise: typeof ResultAsync.fromSafePromise; +declare const fromAsyncThrowable: typeof ResultAsync.fromThrowable; +declare type CombineResultAsyncs[]> = IsLiteralArray extends 1 ? TraverseAsync> : ResultAsync, ExtractErrAsyncTypes[number]>; +declare type CombineResultsWithAllErrorsArrayAsync[]> = IsLiteralArray extends 1 ? TraverseWithAllErrorsAsync> : ResultAsync, ExtractErrAsyncTypes[number][]>; +declare type UnwrapAsync = IsLiteralArray extends 1 ? Writable extends [infer H, ...infer Rest] ? H extends PromiseLike ? HI extends Result ? [Dedup, ...UnwrapAsync] : never : never : [] : T extends Array ? A extends PromiseLike ? HI extends Result ? Ok[] : never : never : never; +declare type TraverseAsync = IsLiteralArray extends 1 ? Combine extends [infer Oks, infer Errs] ? ResultAsync, MembersToUnion> : never : T extends Array ? Combine, Depth> extends [infer Oks, infer Errs] ? Oks extends unknown[] ? Errs extends unknown[] ? ResultAsync, MembersToUnion> : ResultAsync, Errs> : Errs extends unknown[] ? ResultAsync> : ResultAsync : never : never; +declare type TraverseWithAllErrorsAsync = TraverseAsync extends ResultAsync ? ResultAsync : never; +declare type Writable = T extends ReadonlyArray ? [...T] : T; + +declare type ExtractOkTypes[]> = { + [idx in keyof T]: T[idx] extends Result ? U : never; +}; +declare type ExtractOkAsyncTypes[]> = { + [idx in keyof T]: T[idx] extends ResultAsync ? U : never; +}; +declare type ExtractErrTypes[]> = { + [idx in keyof T]: T[idx] extends Result ? E : never; +}; +declare type ExtractErrAsyncTypes[]> = { + [idx in keyof T]: T[idx] extends ResultAsync ? E : never; +}; +declare type InferOkTypes = R extends Result ? T : never; +declare type InferErrTypes = R extends Result ? E : never; +declare type InferAsyncOkTypes = R extends ResultAsync ? T : never; +declare type InferAsyncErrTypes = R extends ResultAsync ? E : never; + +declare namespace Result { + /** + * Wraps a function with a try catch, creating a new function with the same + * arguments but returning `Ok` if successful, `Err` if the function throws + * + * @param fn function to wrap with ok on success or err on failure + * @param errorFn when an error is thrown, this will wrap the error result if provided + */ + function fromThrowable unknown, E>(fn: Fn, errorFn?: (e: unknown) => E): (...args: Parameters) => Result, E>; + function combine, ...Result[]]>(resultList: T): CombineResults; + function combine[]>(resultList: T): CombineResults; + function combineWithAllErrors, ...Result[]]>(resultList: T): CombineResultsWithAllErrorsArray; + function combineWithAllErrors[]>(resultList: T): CombineResultsWithAllErrorsArray; +} +declare type Result = Ok | Err; +declare function ok(value: T): Ok; +declare function ok(value: void): Ok; +declare function err(err: E): Err; +declare function err(err: E): Err; +declare function err(err: void): Err; +/** + * Evaluates the given generator to a Result returned or an Err yielded from it, + * whichever comes first. + * + * This function is intended to emulate Rust's ? operator. + * See `/tests/safeTry.test.ts` for examples. + * + * @param body - What is evaluated. In body, `yield* result` works as + * Rust's `result?` expression. + * @returns The first occurrence of either an yielded Err or a returned Result. + */ +declare function safeTry(body: () => Generator, Result>): Result; +declare function safeTry, GeneratorReturnResult extends Result>(body: () => Generator): Result, InferErrTypes | InferErrTypes>; +/** + * Evaluates the given generator to a Result returned or an Err yielded from it, + * whichever comes first. + * + * This function is intended to emulate Rust's ? operator. + * See `/tests/safeTry.test.ts` for examples. + * + * @param body - What is evaluated. In body, `yield* result` and + * `yield* resultAsync` work as Rust's `result?` expression. + * @returns The first occurrence of either an yielded Err or a returned Result. + */ +declare function safeTry(body: () => AsyncGenerator, Result>): ResultAsync; +declare function safeTry, GeneratorReturnResult extends Result>(body: () => AsyncGenerator): ResultAsync, InferErrTypes | InferErrTypes>; +interface IResult { + /** + * Used to check if a `Result` is an `OK` + * + * @returns `true` if the result is an `OK` variant of Result + */ + isOk(): this is Ok; + /** + * Used to check if a `Result` is an `Err` + * + * @returns `true` if the result is an `Err` variant of Result + */ + isErr(): this is Err; + /** + * Maps a `Result` to `Result` + * by applying a function to a contained `Ok` value, leaving an `Err` value + * untouched. + * + * @param f The function to apply an `OK` value + * @returns the result of applying `f` or an `Err` untouched + */ + map(f: (t: T) => A): Result; + /** + * Maps a `Result` to `Result` by applying a function to a + * contained `Err` value, leaving an `Ok` value untouched. + * + * This function can be used to pass through a successful result while + * handling an error. + * + * @param f a function to apply to the error `Err` value + */ + mapErr(f: (e: E) => U): Result; + /** + * Similar to `map` Except you must return a new `Result`. + * + * This is useful for when you need to do a subsequent computation using the + * inner `T` value, but that computation might fail. + * Additionally, `andThen` is really useful as a tool to flatten a + * `Result, E1>` into a `Result` (see example below). + * + * @param f The function to apply to the current value + */ + andThen>(f: (t: T) => R): Result, InferErrTypes | E>; + andThen(f: (t: T) => Result): Result; + /** + * This "tee"s the current value to an passed-in computation such as side + * effect functions but still returns the same current value as the result. + * + * This is useful when you want to pass the current result to your side-track + * work such as logging but want to continue main-track work after that. + * This method does not care about the result of the passed in computation. + * + * @param f The function to apply to the current value + */ + andTee(f: (t: T) => unknown): Result; + /** + * This "tee"s the current `Err` value to an passed-in computation such as side + * effect functions but still returns the same `Err` value as the result. + * + * This is useful when you want to pass the current `Err` value to your side-track + * work such as logging but want to continue error-track work after that. + * This method does not care about the result of the passed in computation. + * + * @param f The function to apply to the current `Err` value + */ + orTee(f: (t: E) => unknown): Result; + /** + * Similar to `andTee` except error result of the computation will be passed + * to the downstream in case of an error. + * + * This version is useful when you want to make side-effects but in case of an + * error, you want to pass the error to the downstream. + * + * @param f The function to apply to the current value + */ + andThrough>(f: (t: T) => R): Result | E>; + andThrough(f: (t: T) => Result): Result; + /** + * Takes an `Err` value and maps it to a `Result`. + * + * This is useful for error recovery. + * + * + * @param f A function to apply to an `Err` value, leaving `Ok` values + * untouched. + */ + orElse>(f: (e: E) => R): Result | T, InferErrTypes>; + orElse(f: (e: E) => Result): Result; + /** + * Similar to `map` Except you must return a new `Result`. + * + * This is useful for when you need to do a subsequent async computation using + * the inner `T` value, but that computation might fail. Must return a ResultAsync + * + * @param f The function that returns a `ResultAsync` to apply to the current + * value + */ + asyncAndThen(f: (t: T) => ResultAsync): ResultAsync; + /** + * Maps a `Result` to `ResultAsync` + * by applying an async function to a contained `Ok` value, leaving an `Err` + * value untouched. + * + * @param f An async function to apply an `OK` value + */ + asyncMap(f: (t: T) => Promise): ResultAsync; + /** + * Unwrap the `Ok` value, or return the default if there is an `Err` + * + * @param v the default value to return if there is an `Err` + */ + unwrapOr(v: A): T | A; + /** + * + * Given 2 functions (one for the `Ok` variant and one for the `Err` variant) + * execute the function that matches the `Result` variant. + * + * Match callbacks do not necessitate to return a `Result`, however you can + * return a `Result` if you want to. + * + * `match` is like chaining `map` and `mapErr`, with the distinction that + * with `match` both functions must have the same return type. + * + * @param ok + * @param err + */ + match(ok: (t: T) => A, err: (e: E) => B): A | B; + /** + * @deprecated will be removed in 9.0.0. + * + * You can use `safeTry` without this method. + * @example + * ```typescript + * safeTry(function* () { + * const okValue = yield* yourResult + * }) + * ``` + * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`. + */ + safeUnwrap(): Generator, T>; + /** + * **This method is unsafe, and should only be used in a test environments** + * + * Takes a `Result` and returns a `T` when the result is an `Ok`, otherwise it throws a custom object. + * + * @param config + */ + _unsafeUnwrap(config?: ErrorConfig): T; + /** + * **This method is unsafe, and should only be used in a test environments** + * + * takes a `Result` and returns a `E` when the result is an `Err`, + * otherwise it throws a custom object. + * + * @param config + */ + _unsafeUnwrapErr(config?: ErrorConfig): E; +} +declare class Ok implements IResult { + readonly value: T; + constructor(value: T); + isOk(): this is Ok; + isErr(): this is Err; + map(f: (t: T) => A): Result; + mapErr(_f: (e: E) => U): Result; + andThen>(f: (t: T) => R): Result, InferErrTypes | E>; + andThen(f: (t: T) => Result): Result; + andThrough>(f: (t: T) => R): Result | E>; + andThrough(f: (t: T) => Result): Result; + andTee(f: (t: T) => unknown): Result; + orTee(_f: (t: E) => unknown): Result; + orElse>(_f: (e: E) => R): Result | T, InferErrTypes>; + orElse(_f: (e: E) => Result): Result; + asyncAndThen(f: (t: T) => ResultAsync): ResultAsync; + asyncAndThrough>(f: (t: T) => R): ResultAsync | E>; + asyncAndThrough(f: (t: T) => ResultAsync): ResultAsync; + asyncMap(f: (t: T) => Promise): ResultAsync; + unwrapOr(_v: A): T | A; + match(ok: (t: T) => A, _err: (e: E) => B): A | B; + safeUnwrap(): Generator, T>; + _unsafeUnwrap(_?: ErrorConfig): T; + _unsafeUnwrapErr(config?: ErrorConfig): E; + [Symbol.iterator](): Generator, T>; +} +declare class Err implements IResult { + readonly error: E; + constructor(error: E); + isOk(): this is Ok; + isErr(): this is Err; + map(_f: (t: T) => A): Result; + mapErr(f: (e: E) => U): Result; + andThrough(_f: (t: T) => Result): Result; + andTee(_f: (t: T) => unknown): Result; + orTee(f: (t: E) => unknown): Result; + andThen>(_f: (t: T) => R): Result, InferErrTypes | E>; + andThen(_f: (t: T) => Result): Result; + orElse>(f: (e: E) => R): Result | T, InferErrTypes>; + orElse(f: (e: E) => Result): Result; + asyncAndThen(_f: (t: T) => ResultAsync): ResultAsync; + asyncAndThrough(_f: (t: T) => ResultAsync): ResultAsync; + asyncMap(_f: (t: T) => Promise): ResultAsync; + unwrapOr(v: A): T | A; + match(_ok: (t: T) => A, err: (e: E) => B): A | B; + safeUnwrap(): Generator, T>; + _unsafeUnwrap(config?: ErrorConfig): T; + _unsafeUnwrapErr(_?: ErrorConfig): E; + [Symbol.iterator](): Generator, T>; +} +declare const fromThrowable: typeof Result.fromThrowable; +declare type Prev = [ + never, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + ...0[] +]; +declare type CollectResults = [ + Depth +] extends [never] ? [] : T extends [infer H, ...infer Rest] ? H extends Result ? CollectResults : never : Collected; +declare type Transpose = A extends [infer T, ...infer Rest] ? T extends [infer L, infer R] ? Transposed extends [infer PL, infer PR] ? PL extends unknown[] ? PR extends unknown[] ? Transpose : never : never : Transpose : Transposed : Transposed; +declare type Combine = Transpose, [], Depth> extends [ + infer L, + infer R +] ? [UnknownMembersToNever, UnknownMembersToNever] : Transpose, [], Depth> extends [] ? [[], []] : never; +declare type Dedup = T extends Result ? [unknown] extends [RL] ? Err : Ok : T; +declare type MemberListOf = ((T extends unknown ? (t: T) => T : never) extends infer U ? (U extends unknown ? (u: U) => unknown : never) extends (v: infer V) => unknown ? V : never : never) extends (_: unknown) => infer W ? [...MemberListOf>, W] : []; +declare type EmptyArrayToNever = T extends [] ? never : NeverArrayToNever extends 1 ? T extends [never, ...infer Rest] ? [EmptyArrayToNever] extends [never] ? never : T : T : T; +declare type UnknownMembersToNever = T extends [infer H, ...infer R] ? [[unknown] extends [H] ? never : H, ...UnknownMembersToNever] : T; +declare type MembersToUnion = T extends unknown[] ? T[number] : never; +declare type IsLiteralArray = T extends { + length: infer L; +} ? L extends number ? number extends L ? 0 : 1 : 0 : 0; +declare type Traverse = Combine extends [infer Oks, infer Errs] ? Result, MembersToUnion> : never; +declare type TraverseWithAllErrors = Traverse extends Result ? Result : never; +declare type CombineResults[]> = IsLiteralArray extends 1 ? Traverse : Result, ExtractErrTypes[number]>; +declare type CombineResultsWithAllErrorsArray[]> = IsLiteralArray extends 1 ? TraverseWithAllErrors : Result, ExtractErrTypes[number][]>; + + + +type Encoder = (value: T) => Uint8Array; +type Decoder = (value: Uint8Array | ArrayBuffer | string) => T; +type Codec = [Encoder, Decoder] & { + enc: Encoder; + dec: Decoder; +}; +type ResultPayload = + | { success: true; value: Ok } + | { success: false; value: Err }; +type HexString = `0x${string}`; +type CallErrorValue = + | { tag: "Domain"; value: DomainError } + | { tag: "Denied"; value?: undefined } + | { tag: "Unsupported"; value?: undefined } + | { tag: "MalformedFrame"; value: { reason: string } } + | { tag: "HostFailure"; value: { reason: string } }; + +declare namespace T { +/** A 32-byte raw account identifier used for legacy (non-product) accounts. */ +export type AccountId = HexString; +export const AccountId: Codec; +/** Payload when a user clicks an action button. */ +export interface ActionTrigger { + /** + * Message containing the action, as returned by `Chat::post_message` in + * [`HostChatPostMessageResponse::message_id`]. + */ + messageId: string; + /** Which action was triggered. */ + actionId: string; + /** Optional additional data. */ + payload?: HexString; +} +export const ActionTrigger: Codec; +/** + * A resource the host can pre-allocate on behalf of the product (RFC 0010). + * + * For the slot-table allowances (`StatementStoreAllowance`, + * `BulletinAllowance`, `SmartContractAllowance`), pre-allocation is + * opportunistic and the host may also fulfil the allowance implicitly on the + * first submission. `AutoSigning` must be requested explicitly through this + * call. + */ +export type AllocatableResource = +/** Statement Store slot allowance for the product's own allowance account. */ +{ + tag: "StatementStoreAllowance"; + value?: undefined; +} +/** Bulletin chain slot allowance for the product's own allowance account. */ + | { + tag: "BulletinAllowance"; + value?: undefined; +} +/** + * Pre-warmed PGAS balance for the product account selected by this + * derivation index. + */ + | { + tag: "SmartContractAllowance"; + value: DerivationIndex; +} +/** Permission to sign on the product's behalf without per-call user prompts. */ + | { + tag: "AutoSigning"; + value?: undefined; +}; +export const AllocatableResource: Codec; +/** Outcome of allocating a single resource (RFC 0010). */ +export type AllocationOutcome = "Allocated" | "Rejected" | "NotAvailable"; +export const AllocationOutcome: Codec; +/** Layout arrangement (like CSS flexbox `justify-content`). */ +export type Arrangement = "Start" | "End" | "Center" | "SpaceBetween" | "SpaceAround" | "SpaceEvenly"; +export const Arrangement: Codec; +/** Background styling. */ +export interface Background { + /** Background color. */ + color: ColorToken; + /** Background shape. */ + shape?: Shape; +} +export const Background: Codec; +/** + * Balance amount for payment operations. Interpreted according to the host's + * single fixed payment asset (e.g. pUSD). + */ +export type Balance = bigint; +export const Balance: Codec; +/** Border styling. */ +export interface BorderStyle { + /** Border width. */ + width: Size; + /** Border color. */ + color: ColorToken; + /** Border shape. */ + shape?: Shape; +} +export const BorderStyle: Codec; +/** Properties for a [`CustomRendererNode::Box`] container. */ +export interface BoxProps { + /** Content alignment within the box. */ + contentAlignment?: ContentAlignment; +} +export const BoxProps: Codec; +/** Properties for a [`CustomRendererNode::Button`]. */ +export interface ButtonProps { + /** Button label text. */ + text: string; + /** Button style variant. */ + variant?: ButtonVariant; + /** Whether the button is enabled. Absent leaves the default to the host. */ + enabled: OptionalBool; + /** Whether the button shows a loading state. Absent leaves the default to the host. */ + loading: OptionalBool; + /** Action identifier triggered on click. */ + clickAction?: string; +} +export const ButtonProps: Codec; +/** Button style variants. */ +export type ButtonVariant = "Primary" | "Secondary" | "Text"; +export const ButtonVariant: Codec; +/** + * A 32-byte value, passed as plain bytes on FFI surfaces. Version-neutral: + * the FFI conversion below applies to `[u8; 32]` fields in every protocol + * version. + */ +export type Bytes32 = HexString; +export const Bytes32: Codec; +/** Role of a chain within the host's configured environment. */ +export type ChainIdentifier = "Relay" | "AssetHub" | "People" | "Bulletin"; +export const ChainIdentifier: Codec; +/** A clickable action button in a chat message. */ +export interface ChatAction { + /** Action identifier. */ + actionId: string; + /** Button label. */ + title: string; +} +export const ChatAction: Codec; +/** Layout for action buttons. */ +export type ChatActionLayout = "Column" | "Grid"; +export const ChatActionLayout: Codec; +/** Payload of a received chat action. */ +export type ChatActionPayload = +/** A peer posted a message. */ +{ + tag: "MessagePosted"; + value: ChatMessageContent; +} +/** A user triggered an action button. */ + | { + tag: "ActionTriggered"; + value: ActionTrigger; +} +/** A user issued a command. */ + | { + tag: "Command"; + value: ChatCommand; +}; +export const ChatActionPayload: Codec; +/** A set of action buttons with optional text. */ +export interface ChatActions { + /** Optional message text. */ + text?: string; + /** List of action buttons. */ + actions: Array; + /** `Column` or `Grid` layout. */ + layout: ChatActionLayout; +} +export const ChatActions: Codec; +/** Whether the bot was newly registered or already existed. */ +export type ChatBotRegistrationStatus = "New" | "Exists"; +export const ChatBotRegistrationStatus: Codec; +/** A slash command from a chat user. */ +export interface ChatCommand { + /** Command name. */ + command: string; + /** Command arguments. */ + payload: string; +} +export const ChatCommand: Codec; +/** A custom message with application-defined type and binary payload. */ +export interface ChatCustomMessage { + /** Application-defined type key. */ + messageType: string; + /** Binary payload. */ + payload: HexString; +} +export const ChatCustomMessage: Codec; +/** A file attachment in a chat message. */ +export interface ChatFile { + /** File download URL. */ + url: string; + /** File name. */ + fileName: string; + /** MIME type. */ + mimeType: string; + /** File size in bytes. */ + sizeBytes: bigint; + /** Optional caption text. */ + text?: string; +} +export const ChatFile: Codec; +/** A media attachment. */ +export interface ChatMedia { + /** Media URL. */ + url: string; +} +export const ChatMedia: Codec; +/** Content of a chat message -- one of several types. */ +export type ChatMessageContent = +/** Plain text message. */ +{ + tag: "Text"; + value: { + text: string; + }; +} +/** Rich text with media. */ + | { + tag: "RichText"; + value: ChatRichText; +} +/** Action button set. */ + | { + tag: "Actions"; + value: ChatActions; +} +/** File attachment. */ + | { + tag: "File"; + value: ChatFile; +} +/** Emoji reaction. */ + | { + tag: "Reaction"; + value: ChatReaction; +} +/** Reaction removal. */ + | { + tag: "ReactionRemoved"; + value: ChatReaction; +} +/** Custom message. */ + | { + tag: "Custom"; + value: ChatCustomMessage; +}; +export const ChatMessageContent: Codec; +/** A reaction to a chat message. */ +export interface ChatReaction { + /** Message being reacted to. */ + messageId: string; + /** Emoji reaction. */ + emoji: string; +} +export const ChatReaction: Codec; +/** Rich text message with optional media. */ +export interface ChatRichText { + /** Optional text content. */ + text?: string; + /** Attached media items. */ + media: Array; +} +export const ChatRichText: Codec; +/** A chat room the product participates in. */ +export interface ChatRoom { + /** Room identifier. */ + roomId: string; + /** `RoomHost` or `Bot`. */ + participatingAs: ChatRoomParticipation; +} +export const ChatRoom: Codec; +/** How the product participates in a chat room. */ +export type ChatRoomParticipation = "RoomHost" | "Bot"; +export const ChatRoomParticipation: Codec; +/** Whether the room was newly created or already existed. */ +export type ChatRoomRegistrationStatus = "New" | "Exists"; +export const ChatRoomRegistrationStatus: Codec; +/** Balance amount for CoinPayment operations. */ +export type CoinPaymentBalance = number; +export const CoinPaymentBalance: Codec; +/** Standardized encrypted Coinage secret transmission payload. */ +export interface CoinPaymentCheque { + /** Receivable public key protecting the cheque contents. */ + id: CoinPaymentReceivable; + /** Claimed payment amount. */ + amount: CoinPaymentBalance; + /** Concatenated coin secrets encrypted to the receivable. */ + encryptedSecrets: HexString; +} +export const CoinPaymentCheque: Codec; +/** Product-visible clearing reference for reconciliation and receipts. */ +export interface CoinPaymentClearingReference { + /** Clearing Merkle root. */ + root: CoinPaymentMerkleRoot; + /** Product-visible coin key and transaction hash leaves. */ + leaves: Array<[CoinPaymentCoinagePubKey, CoinPaymentTransactionHash]>; +} +export const CoinPaymentClearingReference: Codec; +/** Public Coinage key referenced by clearing evidence. */ +export type CoinPaymentCoinagePubKey = HexString; +export const CoinPaymentCoinagePubKey: Codec; +/** Errors returned by CoinPayment host operations. */ +export type CoinPaymentError = "BalanceLow" | "Denied" | "BadCoins" | "SnipedCoins" | "PurseNotFound" | "ReceivableNotFound" | "UnsupportedChannel" | "UserAgentCapabilityUnavailable" | "Internal"; +export const CoinPaymentError: Codec; +/** Merkle root for a product-visible clearing reference. */ +export type CoinPaymentMerkleRoot = HexString; +export const CoinPaymentMerkleRoot: Codec; +/** Authenticated product identifier recorded for a product-created purse. */ +export type CoinPaymentProductId = string; +export const CoinPaymentProductId: Codec; +/** RFC 0017 CoinPayment purse identifier. */ +export type CoinPaymentPurseId = number; +export const CoinPaymentPurseId: Codec; +/** Product-visible metadata and balance state for a CoinPayment purse. */ +export interface CoinPaymentPurseInfo { + /** Human-readable purse name supplied by the creating product. */ + name: string; + /** Creation timestamp. */ + created: CoinPaymentTimestamp; + /** Product that created the purse. */ + creator: CoinPaymentProductId; + /** Current product-visible balance. */ + balance: CoinPaymentBalance; +} +export const CoinPaymentPurseInfo: Codec; +/** Public key identifying a CoinPayment receivable. */ +export type CoinPaymentReceivable = HexString; +export const CoinPaymentReceivable: Codec; +/** Clearing status stream item. */ +export type CoinPaymentStatus = +/** More coins have cleared. */ +{ + tag: "Clearing"; + value: { + clearing: CoinPaymentBalance; + cleared: CoinPaymentBalance; + }; +} +/** Some or all coins failed to transfer. */ + | { + tag: "Failed"; + value: { + error: CoinPaymentError; + cleared: CoinPaymentBalance; + reference: CoinPaymentClearingReference; + }; +} +/** All coins cleared. */ + | { + tag: "Done"; + value: { + cleared: CoinPaymentBalance; + reference: CoinPaymentClearingReference; + }; +}; +export const CoinPaymentStatus: Codec; +/** Milliseconds since Unix epoch. */ +export type CoinPaymentTimestamp = bigint; +export const CoinPaymentTimestamp: Codec; +/** Transaction hash for a product-visible clearing reference. */ +export type CoinPaymentTransactionHash = HexString; +export const CoinPaymentTransactionHash: Codec; +/** Standardized cheque transmission channel. */ +export type CoinPaymentTransmissionChannel = +/** Statement-store/HOP handoff identified by an SSS topic. */ +{ + tag: "Standard"; + value: { + sssTopic: HexString; + }; +}; +export const CoinPaymentTransmissionChannel: Codec; +/** Semantic color tokens for theming. */ +export type ColorToken = "FgPrimary" | "FgSecondary" | "FgTertiary" | "BgSurfaceMain" | "BgSurfaceContainer" | "BgSurfaceNested" | "FgSuccess" | "FgError" | "FgWarning"; +export const ColorToken: Codec; +/** Properties for a [`CustomRendererNode::Column`] layout. */ +export interface ColumnProps { + /** Horizontal alignment of children. */ + horizontalAlignment?: HorizontalAlignment; + /** Vertical arrangement of children. */ + verticalArrangement?: Arrangement; +} +export const ColumnProps: Codec; +/** 2D content alignment. */ +export type ContentAlignment = "TopStart" | "TopCenter" | "TopEnd" | "CenterStart" | "Center" | "CenterEnd" | "BottomStart" | "BottomCenter" | "BottomEnd"; +export const ContentAlignment: Codec; +/** A privacy-preserving alias derived via ring VRF, bound to a specific context. */ +export interface ContextualAlias { + /** 32-byte context identifier the alias is bound to. */ + context: HexString; + /** Ring VRF alias (variable length). */ + alias: HexString; +} +export const ContextualAlias: Codec; +/** + * A node in the custom renderer UI tree. Component variants contain recursive + * `children` fields. + */ +export type CustomRendererNode = +/** Empty node. */ +{ + tag: "Nil"; + value?: undefined; +} +/** Raw text string. */ + | { + tag: "String"; + value: { + text: string; + }; +} +/** Generic container. */ + | { + tag: "Box"; + value: { + modifiers: Array; + props: BoxProps; + children: Array; + }; +} +/** Vertical layout. */ + | { + tag: "Column"; + value: { + modifiers: Array; + props: ColumnProps; + children: Array; + }; +} +/** Horizontal layout. */ + | { + tag: "Row"; + value: { + modifiers: Array; + props: RowProps; + children: Array; + }; +} +/** Flexible space. */ + | { + tag: "Spacer"; + value: { + modifiers: Array; + children: Array; + }; +} +/** Text display. */ + | { + tag: "Text"; + value: { + modifiers: Array; + props: TextProps; + children: Array; + }; +} +/** Interactive button. */ + | { + tag: "Button"; + value: { + modifiers: Array; + props: ButtonProps; + children: Array; + }; +} +/** Text input. */ + | { + tag: "TextField"; + value: { + modifiers: Array; + props: TextFieldProps; + children: Array; + }; +}; +export const CustomRendererNode: Codec; +/** + * Account selector within a product subtree. Encodes as + * `Either` on the wire (`Index` = left, `Raw` = right). + * + * `Index` is the primary form — plain indices keep a product's accounts + * enumerable. `Raw` carries a raw 32-byte derivation index for cases where + * bytes are genuinely necessary. Hosts expand `Index(n)` to the internal + * 32-byte index (`u32` little-endian plus the index magic). + */ +export type DerivationIndex = +/** Plain account index. */ +{ + tag: "Index"; + value: number; +} +/** Raw 32-byte derivation index. */ + | { + tag: "Raw"; + value: HexString; +}; +export const DerivationIndex: Codec; +/** + * CSS-like dimensions: (top, end, bottom, start). + * Bottom defaults to top, start defaults to end when `None`. + */ +export interface Dimensions { + /** Top dimension. */ + top: Size; + /** End dimension. */ + end: Size; + /** Bottom dimension. Defaults to top when absent. */ + bottom?: Size; + /** Start dimension. Defaults to end when absent. */ + start?: Size; +} +export const Dimensions: Codec; +/** + * Generic error payload carrying a human-readable reason string. Used by many + * methods as a catch-all error type. + */ +export interface GenericError { + /** Human-readable failure reason. */ + reason: string; +} +export const GenericError: Codec; +/** A 32-byte chain genesis hash used to identify the target chain. */ +export type GenesisHash = HexString; +export const GenesisHash: Codec; +/** Horizontal alignment options. */ +export type HorizontalAlignment = "Start" | "Center" | "End"; +export const HorizontalAlignment: Codec; +/** Versioned envelope for [`HostAccountConnectionStatusSubscribeItem`]. */ +export type VersionedHostAccountConnectionStatusSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountConnectionStatusSubscribeItem; +}; +export const VersionedHostAccountConnectionStatusSubscribeItem: Codec; +/** Versioned envelope for [`HostAccountCreateProofError`]. */ +export type VersionedHostAccountCreateProofError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountCreateProofError; +}; +export const VersionedHostAccountCreateProofError: Codec; +/** Versioned envelope for [`HostAccountCreateProofRequest`]. */ +export type VersionedHostAccountCreateProofRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountCreateProofRequest; +}; +export const VersionedHostAccountCreateProofRequest: Codec; +/** Versioned envelope for [`HostAccountCreateProofResponse`]. */ +export type VersionedHostAccountCreateProofResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountCreateProofResponse; +}; +export const VersionedHostAccountCreateProofResponse: Codec; +/** Versioned envelope for [`HostAccountGetAliasError`]. */ +export type VersionedHostAccountGetAliasError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountGetAliasError; +}; +export const VersionedHostAccountGetAliasError: Codec; +/** Versioned envelope for [`HostAccountGetAliasRequest`]. */ +export type VersionedHostAccountGetAliasRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountGetAliasRequest; +}; +export const VersionedHostAccountGetAliasRequest: Codec; +/** Versioned envelope for [`HostAccountGetAliasResponse`]. */ +export type VersionedHostAccountGetAliasResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: ContextualAlias; +}; +export const VersionedHostAccountGetAliasResponse: Codec; +/** Versioned envelope for [`HostAccountGetError`]. */ +export type VersionedHostAccountGetError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountGetError; +}; +export const VersionedHostAccountGetError: Codec; +/** Versioned envelope for [`HostAccountGetRequest`]. */ +export type VersionedHostAccountGetRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountGetRequest; +}; +export const VersionedHostAccountGetRequest: Codec; +/** Versioned envelope for [`HostAccountGetResponse`]. */ +export type VersionedHostAccountGetResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountGetResponse; +}; +export const VersionedHostAccountGetResponse: Codec; +/** Versioned envelope for [`HostAccountListRingVrfKeysError`]. */ +export type VersionedHostAccountListRingVrfKeysError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountListRingVrfKeysError; +}; +export const VersionedHostAccountListRingVrfKeysError: Codec; +/** Versioned envelope for [`HostAccountListRingVrfKeysRequest`]. */ +export type VersionedHostAccountListRingVrfKeysRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountListRingVrfKeysRequest; +}; +export const VersionedHostAccountListRingVrfKeysRequest: Codec; +/** Versioned envelope for [`HostAccountListRingVrfKeysResponse`]. */ +export type VersionedHostAccountListRingVrfKeysResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: Array; +}; +export const VersionedHostAccountListRingVrfKeysResponse: Codec; +/** Versioned envelope for [`HostAccountRegisterRingVrfKeyError`]. */ +export type VersionedHostAccountRegisterRingVrfKeyError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountRegisterRingVrfKeyError; +}; +export const VersionedHostAccountRegisterRingVrfKeyError: Codec; +/** Versioned envelope for [`HostAccountRegisterRingVrfKeyRequest`]. */ +export type VersionedHostAccountRegisterRingVrfKeyRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountRegisterRingVrfKeyRequest; +}; +export const VersionedHostAccountRegisterRingVrfKeyRequest: Codec; +/** Versioned envelope for [`HostAccountRegisterRingVrfKeyResponse`]. */ +export type VersionedHostAccountRegisterRingVrfKeyResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RingVrfPublicKey; +}; +export const VersionedHostAccountRegisterRingVrfKeyResponse: Codec; +/** Versioned envelope for [`HostAccountRingVrfSignError`]. */ +export type VersionedHostAccountRingVrfSignError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountRingVrfSignError; +}; +export const VersionedHostAccountRingVrfSignError: Codec; +/** Versioned envelope for [`HostAccountRingVrfSignRequest`]. */ +export type VersionedHostAccountRingVrfSignRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountRingVrfSignRequest; +}; +export const VersionedHostAccountRingVrfSignRequest: Codec; +/** Versioned envelope for [`HostAccountRingVrfSignResponse`]. */ +export type VersionedHostAccountRingVrfSignResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HexString; +}; +export const VersionedHostAccountRingVrfSignResponse: Codec; +/** Versioned envelope for [`HostAccountSignVrfError`]. */ +export type VersionedHostAccountSignVrfError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountSignVrfError; +}; +export const VersionedHostAccountSignVrfError: Codec; +/** Versioned envelope for [`HostAccountSignVrfRequest`]. */ +export type VersionedHostAccountSignVrfRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountSignVrfRequest; +}; +export const VersionedHostAccountSignVrfRequest: Codec; +/** Versioned envelope for [`HostAccountSignVrfResponse`]. */ +export type VersionedHostAccountSignVrfResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: VrfSignature; +}; +export const VersionedHostAccountSignVrfResponse: Codec; +/** Versioned envelope for [`HostChatActionSubscribeItem`]. */ +export type VersionedHostChatActionSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatActionSubscribeItem; +}; +export const VersionedHostChatActionSubscribeItem: Codec; +/** Versioned envelope for [`HostChatCreateRoomError`]. */ +export type VersionedHostChatCreateRoomError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatCreateRoomError; +}; +export const VersionedHostChatCreateRoomError: Codec; +/** Versioned envelope for [`HostChatCreateRoomRequest`]. */ +export type VersionedHostChatCreateRoomRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatCreateRoomRequest; +}; +export const VersionedHostChatCreateRoomRequest: Codec; +/** Versioned envelope for [`HostChatCreateRoomResponse`]. */ +export type VersionedHostChatCreateRoomResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatCreateRoomResponse; +}; +export const VersionedHostChatCreateRoomResponse: Codec; +/** Versioned envelope for [`HostChatListSubscribeItem`]. */ +export type VersionedHostChatListSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatListSubscribeItem; +}; +export const VersionedHostChatListSubscribeItem: Codec; +/** Versioned envelope for [`HostChatPostMessageError`]. */ +export type VersionedHostChatPostMessageError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatPostMessageError; +}; +export const VersionedHostChatPostMessageError: Codec; +/** Versioned envelope for [`HostChatPostMessageRequest`]. */ +export type VersionedHostChatPostMessageRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatPostMessageRequest; +}; +export const VersionedHostChatPostMessageRequest: Codec; +/** Versioned envelope for [`HostChatPostMessageResponse`]. */ +export type VersionedHostChatPostMessageResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatPostMessageResponse; +}; +export const VersionedHostChatPostMessageResponse: Codec; +/** Versioned envelope for [`HostChatRegisterBotError`]. */ +export type VersionedHostChatRegisterBotError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatRegisterBotError; +}; +export const VersionedHostChatRegisterBotError: Codec; +/** Versioned envelope for [`HostChatRegisterBotRequest`]. */ +export type VersionedHostChatRegisterBotRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatRegisterBotRequest; +}; +export const VersionedHostChatRegisterBotRequest: Codec; +/** Versioned envelope for [`HostChatRegisterBotResponse`]. */ +export type VersionedHostChatRegisterBotResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostChatRegisterBotResponse; +}; +export const VersionedHostChatRegisterBotResponse: Codec; +/** Versioned envelope for [`HostCoinPaymentCreateChequeError`]. */ +export type VersionedHostCoinPaymentCreateChequeError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentCreateChequeError: Codec; +/** Versioned envelope for [`HostCoinPaymentCreateChequeRequest`]. */ +export type VersionedHostCoinPaymentCreateChequeRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentCreateChequeRequest; +}; +export const VersionedHostCoinPaymentCreateChequeRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentCreateChequeResponse`]. */ +export type VersionedHostCoinPaymentCreateChequeResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentCreateChequeResponse; +}; +export const VersionedHostCoinPaymentCreateChequeResponse: Codec; +/** Versioned envelope for [`HostCoinPaymentCreatePurseError`]. */ +export type VersionedHostCoinPaymentCreatePurseError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentCreatePurseError: Codec; +/** Versioned envelope for [`HostCoinPaymentCreatePurseRequest`]. */ +export type VersionedHostCoinPaymentCreatePurseRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentCreatePurseRequest; +}; +export const VersionedHostCoinPaymentCreatePurseRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentCreatePurseResponse`]. */ +export type VersionedHostCoinPaymentCreatePurseResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentCreatePurseResponse; +}; +export const VersionedHostCoinPaymentCreatePurseResponse: Codec; +/** Versioned envelope for [`HostCoinPaymentCreateReceivableError`]. */ +export type VersionedHostCoinPaymentCreateReceivableError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentCreateReceivableError: Codec; +/** Versioned envelope for [`HostCoinPaymentCreateReceivableRequest`]. */ +export type VersionedHostCoinPaymentCreateReceivableRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentCreateReceivableRequest; +}; +export const VersionedHostCoinPaymentCreateReceivableRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentCreateReceivableResponse`]. */ +export type VersionedHostCoinPaymentCreateReceivableResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentCreateReceivableResponse; +}; +export const VersionedHostCoinPaymentCreateReceivableResponse: Codec; +/** Versioned envelope for [`HostCoinPaymentDeletePurseError`]. */ +export type VersionedHostCoinPaymentDeletePurseError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentDeletePurseError: Codec; +/** Versioned envelope for [`HostCoinPaymentDeletePurseItem`]. */ +export type VersionedHostCoinPaymentDeletePurseItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentStatus; +}; +export const VersionedHostCoinPaymentDeletePurseItem: Codec; +/** Versioned envelope for [`HostCoinPaymentDeletePurseRequest`]. */ +export type VersionedHostCoinPaymentDeletePurseRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentDeletePurseRequest; +}; +export const VersionedHostCoinPaymentDeletePurseRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentDepositError`]. */ +export type VersionedHostCoinPaymentDepositError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentDepositError: Codec; +/** Versioned envelope for [`HostCoinPaymentDepositItem`]. */ +export type VersionedHostCoinPaymentDepositItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentStatus; +}; +export const VersionedHostCoinPaymentDepositItem: Codec; +/** Versioned envelope for [`HostCoinPaymentDepositRequest`]. */ +export type VersionedHostCoinPaymentDepositRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentDepositRequest; +}; +export const VersionedHostCoinPaymentDepositRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentListenForError`]. */ +export type VersionedHostCoinPaymentListenForError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentListenForError: Codec; +/** Versioned envelope for [`HostCoinPaymentListenForItem`]. */ +export type VersionedHostCoinPaymentListenForItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentListenForItem; +}; +export const VersionedHostCoinPaymentListenForItem: Codec; +/** Versioned envelope for [`HostCoinPaymentListenForRequest`]. */ +export type VersionedHostCoinPaymentListenForRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentListenForRequest; +}; +export const VersionedHostCoinPaymentListenForRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentQueryPurseError`]. */ +export type VersionedHostCoinPaymentQueryPurseError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentQueryPurseError: Codec; +/** Versioned envelope for [`HostCoinPaymentQueryPurseRequest`]. */ +export type VersionedHostCoinPaymentQueryPurseRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentQueryPurseRequest; +}; +export const VersionedHostCoinPaymentQueryPurseRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentQueryPurseResponse`]. */ +export type VersionedHostCoinPaymentQueryPurseResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentQueryPurseResponse; +}; +export const VersionedHostCoinPaymentQueryPurseResponse: Codec; +/** Versioned envelope for [`HostCoinPaymentRebalancePurseError`]. */ +export type VersionedHostCoinPaymentRebalancePurseError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentRebalancePurseError: Codec; +/** Versioned envelope for [`HostCoinPaymentRebalancePurseItem`]. */ +export type VersionedHostCoinPaymentRebalancePurseItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentStatus; +}; +export const VersionedHostCoinPaymentRebalancePurseItem: Codec; +/** Versioned envelope for [`HostCoinPaymentRebalancePurseRequest`]. */ +export type VersionedHostCoinPaymentRebalancePurseRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentRebalancePurseRequest; +}; +export const VersionedHostCoinPaymentRebalancePurseRequest: Codec; +/** Versioned envelope for [`HostCoinPaymentRefundError`]. */ +export type VersionedHostCoinPaymentRefundError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentError; +}; +export const VersionedHostCoinPaymentRefundError: Codec; +/** Versioned envelope for [`HostCoinPaymentRefundItem`]. */ +export type VersionedHostCoinPaymentRefundItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CoinPaymentStatus; +}; +export const VersionedHostCoinPaymentRefundItem: Codec; +/** Versioned envelope for [`HostCoinPaymentRefundRequest`]. */ +export type VersionedHostCoinPaymentRefundRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCoinPaymentRefundRequest; +}; +export const VersionedHostCoinPaymentRefundRequest: Codec; +/** Versioned envelope for [`HostCreateTransactionError`]. */ +export type VersionedHostCreateTransactionError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCreateTransactionError; +}; +export const VersionedHostCreateTransactionError: Codec; +/** Versioned envelope for [`HostCreateTransactionRequest`]. */ +export type VersionedHostCreateTransactionRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: ProductAccountTxPayload; +}; +export const VersionedHostCreateTransactionRequest: Codec; +/** Versioned envelope for [`HostCreateTransactionResponse`]. */ +export type VersionedHostCreateTransactionResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCreateTransactionResponse; +}; +export const VersionedHostCreateTransactionResponse: Codec; +/** Versioned envelope for [`HostCreateTransactionWithLegacyAccountError`]. */ +export type VersionedHostCreateTransactionWithLegacyAccountError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCreateTransactionError; +}; +export const VersionedHostCreateTransactionWithLegacyAccountError: Codec; +/** Versioned envelope for [`HostCreateTransactionWithLegacyAccountRequest`]. */ +export type VersionedHostCreateTransactionWithLegacyAccountRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: LegacyAccountTxPayload; +}; +export const VersionedHostCreateTransactionWithLegacyAccountRequest: Codec; +/** Versioned envelope for [`HostCreateTransactionWithLegacyAccountResponse`]. */ +export type VersionedHostCreateTransactionWithLegacyAccountResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostCreateTransactionWithLegacyAccountResponse; +}; +export const VersionedHostCreateTransactionWithLegacyAccountResponse: Codec; +/** Versioned envelope for [`HostDeriveEntropyError`]. */ +export type VersionedHostDeriveEntropyError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostDeriveEntropyError; +}; +export const VersionedHostDeriveEntropyError: Codec; +/** Versioned envelope for [`HostDeriveEntropyRequest`]. */ +export type VersionedHostDeriveEntropyRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostDeriveEntropyRequest; +}; +export const VersionedHostDeriveEntropyRequest: Codec; +/** Versioned envelope for [`HostDeriveEntropyResponse`]. */ +export type VersionedHostDeriveEntropyResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostDeriveEntropyResponse; +}; +export const VersionedHostDeriveEntropyResponse: Codec; +/** Versioned envelope for [`HostDevicePermissionError`]. */ +export type VersionedHostDevicePermissionError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedHostDevicePermissionError: Codec; +/** Versioned envelope for [`HostDevicePermissionRequest`]. */ +export type VersionedHostDevicePermissionRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostDevicePermissionRequest; +}; +export const VersionedHostDevicePermissionRequest: Codec; +/** Versioned envelope for [`HostDevicePermissionResponse`]. */ +export type VersionedHostDevicePermissionResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostDevicePermissionResponse; +}; +export const VersionedHostDevicePermissionResponse: Codec; +/** Versioned envelope for [`HostFeatureSupportedError`]. */ +export type VersionedHostFeatureSupportedError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedHostFeatureSupportedError: Codec; +/** Versioned envelope for [`HostFeatureSupportedRequest`]. */ +export type VersionedHostFeatureSupportedRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostFeatureSupportedRequest; +}; +export const VersionedHostFeatureSupportedRequest: Codec; +/** Versioned envelope for [`HostFeatureSupportedResponse`]. */ +export type VersionedHostFeatureSupportedResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostFeatureSupportedResponse; +}; +export const VersionedHostFeatureSupportedResponse: Codec; +/** Versioned envelope for [`HostGetLegacyAccountsError`]. */ +export type VersionedHostGetLegacyAccountsError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostAccountGetError; +}; +export const VersionedHostGetLegacyAccountsError: Codec; +/** Versioned envelope for [`HostGetLegacyAccountsRequest`]. */ +export type VersionedHostGetLegacyAccountsRequest = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostGetLegacyAccountsRequest: Codec; +/** Versioned envelope for [`HostGetLegacyAccountsResponse`]. */ +export type VersionedHostGetLegacyAccountsResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostGetLegacyAccountsResponse; +}; +export const VersionedHostGetLegacyAccountsResponse: Codec; +/** Versioned envelope for [`HostGetProductContextError`]. */ +export type VersionedHostGetProductContextError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedHostGetProductContextError: Codec; +/** Versioned envelope for [`HostGetProductContextRequest`]. */ +export type VersionedHostGetProductContextRequest = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostGetProductContextRequest: Codec; +/** Versioned envelope for [`HostGetProductContextResponse`]. */ +export type VersionedHostGetProductContextResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostGetProductContextResponse; +}; +export const VersionedHostGetProductContextResponse: Codec; +/** Versioned envelope for [`HostGetUserIdError`]. */ +export type VersionedHostGetUserIdError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostGetUserIdError; +}; +export const VersionedHostGetUserIdError: Codec; +/** Versioned envelope for [`HostGetUserIdRequest`]. */ +export type VersionedHostGetUserIdRequest = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostGetUserIdRequest: Codec; +/** Versioned envelope for [`HostGetUserIdResponse`]. */ +export type VersionedHostGetUserIdResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostGetUserIdResponse; +}; +export const VersionedHostGetUserIdResponse: Codec; +/** Versioned envelope for [`HostHandshakeError`]. */ +export type VersionedHostHandshakeError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostHandshakeError; +}; +export const VersionedHostHandshakeError: Codec; +/** Versioned envelope for [`HostHandshakeRequest`]. */ +export type VersionedHostHandshakeRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostHandshakeRequest; +}; +export const VersionedHostHandshakeRequest: Codec; +/** Versioned envelope for [`HostHandshakeResponse`]. */ +export type VersionedHostHandshakeResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostHandshakeResponse: Codec; +/** + * Identity and version of the host currently running the product. + * + * Reported by [`crate::api::System::host_info`] so a product knows which host + * (and which build of it) is running it — for adapting to the host, + * telemetry, and attributing behaviour to a concrete build in diagnostics and + * bug reports. + */ +export interface HostInfo { + /** Platform category the host runs on. */ + platform: HostPlatform; + /** + * Human-readable name of the host implementation, e.g. `"Polkadot + * Desktop"`, `"Polkadot Mobile"`, or `"dotli"`. Hosts should report a + * stable, non-empty name. + */ + name: string; + /** + * Host-native version string, e.g. a semver such as `"1.2.3"`. Hosts + * should report a non-empty value; the format is the host's own. + */ + version: string; +} +export const HostInfo: Codec; +/** Versioned envelope for [`HostInfoError`]. */ +export type VersionedHostInfoError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedHostInfoError: Codec; +/** Versioned envelope for [`HostInfoRequest`]. */ +export type VersionedHostInfoRequest = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostInfoRequest: Codec; +/** Versioned envelope for [`HostInfoResponse`]. */ +export type VersionedHostInfoResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostInfo; +}; +export const VersionedHostInfoResponse: Codec; +/** Versioned envelope for [`HostLocalStorageClearError`]. */ +export type VersionedHostLocalStorageClearError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostLocalStorageReadError; +}; +export const VersionedHostLocalStorageClearError: Codec; +/** Versioned envelope for [`HostLocalStorageClearRequest`]. */ +export type VersionedHostLocalStorageClearRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostLocalStorageClearRequest; +}; +export const VersionedHostLocalStorageClearRequest: Codec; +/** Versioned envelope for [`HostLocalStorageClearResponse`]. */ +export type VersionedHostLocalStorageClearResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostLocalStorageClearResponse: Codec; +/** Versioned envelope for [`HostLocalStorageReadError`]. */ +export type VersionedHostLocalStorageReadError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostLocalStorageReadError; +}; +export const VersionedHostLocalStorageReadError: Codec; +/** Versioned envelope for [`HostLocalStorageReadRequest`]. */ +export type VersionedHostLocalStorageReadRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostLocalStorageReadRequest; +}; +export const VersionedHostLocalStorageReadRequest: Codec; +/** Versioned envelope for [`HostLocalStorageReadResponse`]. */ +export type VersionedHostLocalStorageReadResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostLocalStorageReadResponse; +}; +export const VersionedHostLocalStorageReadResponse: Codec; +/** Versioned envelope for [`HostLocalStorageWriteError`]. */ +export type VersionedHostLocalStorageWriteError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostLocalStorageReadError; +}; +export const VersionedHostLocalStorageWriteError: Codec; +/** Versioned envelope for [`HostLocalStorageWriteRequest`]. */ +export type VersionedHostLocalStorageWriteRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostLocalStorageWriteRequest; +}; +export const VersionedHostLocalStorageWriteRequest: Codec; +/** Versioned envelope for [`HostLocalStorageWriteResponse`]. */ +export type VersionedHostLocalStorageWriteResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostLocalStorageWriteResponse: Codec; +/** Versioned envelope for [`HostNavigateToError`]. */ +export type VersionedHostNavigateToError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostNavigateToError; +}; +export const VersionedHostNavigateToError: Codec; +/** Versioned envelope for [`HostNavigateToRequest`]. */ +export type VersionedHostNavigateToRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostNavigateToRequest; +}; +export const VersionedHostNavigateToRequest: Codec; +/** Versioned envelope for [`HostNavigateToResponse`]. */ +export type VersionedHostNavigateToResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostNavigateToResponse: Codec; +/** Versioned envelope for [`HostPaymentBalanceSubscribeError`]. */ +export type VersionedHostPaymentBalanceSubscribeError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentBalanceSubscribeError; +}; +export const VersionedHostPaymentBalanceSubscribeError: Codec; +/** Versioned envelope for [`HostPaymentBalanceSubscribeItem`]. */ +export type VersionedHostPaymentBalanceSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentBalanceSubscribeItem; +}; +export const VersionedHostPaymentBalanceSubscribeItem: Codec; +/** Versioned envelope for [`HostPaymentBalanceSubscribeRequest`]. */ +export type VersionedHostPaymentBalanceSubscribeRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentBalanceSubscribeRequest; +}; +export const VersionedHostPaymentBalanceSubscribeRequest: Codec; +/** Versioned envelope for [`HostPaymentError`]. */ +export type VersionedHostPaymentError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentError; +}; +export const VersionedHostPaymentError: Codec; +/** Versioned envelope for [`HostPaymentRequest`]. */ +export type VersionedHostPaymentRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentRequest; +}; +export const VersionedHostPaymentRequest: Codec; +/** Versioned envelope for [`HostPaymentResponse`]. */ +export type VersionedHostPaymentResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentResponse; +}; +export const VersionedHostPaymentResponse: Codec; +/** Versioned envelope for [`HostPaymentStatusSubscribeError`]. */ +export type VersionedHostPaymentStatusSubscribeError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentStatusSubscribeError; +}; +export const VersionedHostPaymentStatusSubscribeError: Codec; +/** Versioned envelope for [`HostPaymentStatusSubscribeItem`]. */ +export type VersionedHostPaymentStatusSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentStatusSubscribeItem; +}; +export const VersionedHostPaymentStatusSubscribeItem: Codec; +/** Versioned envelope for [`HostPaymentStatusSubscribeRequest`]. */ +export type VersionedHostPaymentStatusSubscribeRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentStatusSubscribeRequest; +}; +export const VersionedHostPaymentStatusSubscribeRequest: Codec; +/** Versioned envelope for [`HostPaymentTopUpError`]. */ +export type VersionedHostPaymentTopUpError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentTopUpError; +}; +export const VersionedHostPaymentTopUpError: Codec; +/** Versioned envelope for [`HostPaymentTopUpRequest`]. */ +export type VersionedHostPaymentTopUpRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPaymentTopUpRequest; +}; +export const VersionedHostPaymentTopUpRequest: Codec; +/** Versioned envelope for [`HostPaymentTopUpResponse`]. */ +export type VersionedHostPaymentTopUpResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostPaymentTopUpResponse: Codec; +/** Platform category a host runs on. */ +export type HostPlatform = "Web" | "Android" | "Ios" | "Desktop" | "Cli" | "Unknown"; +export const HostPlatform: Codec; +/** Versioned envelope for [`HostPushNotificationCancelError`]. */ +export type VersionedHostPushNotificationCancelError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedHostPushNotificationCancelError: Codec; +/** Versioned envelope for [`HostPushNotificationCancelRequest`]. */ +export type VersionedHostPushNotificationCancelRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPushNotificationCancelRequest; +}; +export const VersionedHostPushNotificationCancelRequest: Codec; +/** Versioned envelope for [`HostPushNotificationCancelResponse`]. */ +export type VersionedHostPushNotificationCancelResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedHostPushNotificationCancelResponse: Codec; +/** Versioned envelope for [`HostPushNotificationError`]. */ +export type VersionedHostPushNotificationError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPushNotificationError; +}; +export const VersionedHostPushNotificationError: Codec; +/** Versioned envelope for [`HostPushNotificationRequest`]. */ +export type VersionedHostPushNotificationRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPushNotificationRequest; +}; +export const VersionedHostPushNotificationRequest: Codec; +/** Versioned envelope for [`HostPushNotificationResponse`]. */ +export type VersionedHostPushNotificationResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostPushNotificationResponse; +}; +export const VersionedHostPushNotificationResponse: Codec; +/** Versioned envelope for [`HostRequestLoginError`]. */ +export type VersionedHostRequestLoginError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostRequestLoginError; +}; +export const VersionedHostRequestLoginError: Codec; +/** Versioned envelope for [`HostRequestLoginRequest`]. */ +export type VersionedHostRequestLoginRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostRequestLoginRequest; +}; +export const VersionedHostRequestLoginRequest: Codec; +/** Versioned envelope for [`HostRequestLoginResponse`]. */ +export type VersionedHostRequestLoginResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostRequestLoginResponse; +}; +export const VersionedHostRequestLoginResponse: Codec; +/** Versioned envelope for [`HostRequestResourceAllocationError`]. */ +export type VersionedHostRequestResourceAllocationError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: ResourceAllocationError; +}; +export const VersionedHostRequestResourceAllocationError: Codec; +/** Versioned envelope for [`HostRequestResourceAllocationRequest`]. */ +export type VersionedHostRequestResourceAllocationRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostRequestResourceAllocationRequest; +}; +export const VersionedHostRequestResourceAllocationRequest: Codec; +/** Versioned envelope for [`HostRequestResourceAllocationResponse`]. */ +export type VersionedHostRequestResourceAllocationResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostRequestResourceAllocationResponse; +}; +export const VersionedHostRequestResourceAllocationResponse: Codec; +/** + * Full Substrate extrinsic signing payload with all fields needed for signature + * generation. + */ +export interface HostSignPayloadData { + /** Reference block hash. */ + blockHash: HexString; + /** Reference block number. */ + blockNumber: HexString; + /** Mortality era encoding. */ + era: HexString; + /** Chain genesis hash. */ + genesisHash: HexString; + /** SCALE-encoded call data. */ + method: HexString; + /** Account nonce. */ + nonce: HexString; + /** Runtime spec version. */ + specVersion: HexString; + /** Transaction tip. */ + tip: HexString; + /** Transaction format version. */ + transactionVersion: HexString; + /** Extension identifiers. */ + signedExtensions: Array; + /** Extrinsic version. */ + version: number; + /** For multi-asset tips. */ + assetId?: HexString; + /** CheckMetadataHash extension. */ + metadataHash?: HexString; + /** Metadata mode. */ + mode?: number; + /** Request signed transaction back. */ + withSignedTransaction?: boolean; +} +export const HostSignPayloadData: Codec; +/** Versioned envelope for [`HostSignPayloadError`]. */ +export type VersionedHostSignPayloadError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadError; +}; +export const VersionedHostSignPayloadError: Codec; +/** Versioned envelope for [`HostSignPayloadRequest`]. */ +export type VersionedHostSignPayloadRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadRequest; +}; +export const VersionedHostSignPayloadRequest: Codec; +/** Versioned envelope for [`HostSignPayloadResponse`]. */ +export type VersionedHostSignPayloadResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadResponse; +}; +export const VersionedHostSignPayloadResponse: Codec; +/** Versioned envelope for [`HostSignPayloadWithLegacyAccountError`]. */ +export type VersionedHostSignPayloadWithLegacyAccountError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadError; +}; +export const VersionedHostSignPayloadWithLegacyAccountError: Codec; +/** Versioned envelope for [`HostSignPayloadWithLegacyAccountRequest`]. */ +export type VersionedHostSignPayloadWithLegacyAccountRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadWithLegacyAccountRequest; +}; +export const VersionedHostSignPayloadWithLegacyAccountRequest: Codec; +/** Versioned envelope for [`HostSignPayloadWithLegacyAccountResponse`]. */ +export type VersionedHostSignPayloadWithLegacyAccountResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadResponse; +}; +export const VersionedHostSignPayloadWithLegacyAccountResponse: Codec; +/** Versioned envelope for [`HostSignRawError`]. */ +export type VersionedHostSignRawError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadError; +}; +export const VersionedHostSignRawError: Codec; +/** Versioned envelope for [`HostSignRawRequest`]. */ +export type VersionedHostSignRawRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignRawRequest; +}; +export const VersionedHostSignRawRequest: Codec; +/** Versioned envelope for [`HostSignRawResponse`]. */ +export type VersionedHostSignRawResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadResponse; +}; +export const VersionedHostSignRawResponse: Codec; +/** Versioned envelope for [`HostSignRawWithLegacyAccountError`]. */ +export type VersionedHostSignRawWithLegacyAccountError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadError; +}; +export const VersionedHostSignRawWithLegacyAccountError: Codec; +/** Versioned envelope for [`HostSignRawWithLegacyAccountRequest`]. */ +export type VersionedHostSignRawWithLegacyAccountRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignRawWithLegacyAccountRequest; +}; +export const VersionedHostSignRawWithLegacyAccountRequest: Codec; +/** Versioned envelope for [`HostSignRawWithLegacyAccountResponse`]. */ +export type VersionedHostSignRawWithLegacyAccountResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostSignPayloadResponse; +}; +export const VersionedHostSignRawWithLegacyAccountResponse: Codec; +/** Versioned envelope for [`HostThemeSubscribeItem`]. */ +export type VersionedHostThemeSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HostThemeSubscribeItem; +}; +export const VersionedHostThemeSubscribeItem: Codec; +/** + * A user-imported (legacy) account: public key plus an optional user-chosen + * display name. + * + * Returned by [`HostGetLegacyAccountsResponse`]. Distinct from + * [`ProductAccount`], which is protocol-derived and never carries a label. + */ +export interface LegacyAccount { + /** The account public key (variable-length bytes). */ + publicKey: HexString; + /** Optional user-chosen display name. */ + name?: string; +} +export const LegacyAccount: Codec; +/** + * Transaction payload for a legacy (non-product) account. + * + * Identical to [`ProductAccountTxPayload`] except the signer is a raw + * 32-byte [`AccountId`]. + */ +export interface LegacyAccountTxPayload { + /** Raw 32-byte public key of the legacy account. */ + signer: AccountId; + /** Chain where the transaction will execute. */ + genesisHash: GenesisHash; + /** SCALE-encoded Call data. */ + callData: HexString; + /** Transaction extensions supplied by the caller. */ + extensions: Array; + /** 0 for Extrinsic V4, runtime-supported value for V5. */ + txExtVersion: number; +} +export const LegacyAccountTxPayload: Codec; +/** Layout and styling modifiers applied to custom renderer components. */ +export type Modifier = +/** Outer spacing. */ +{ + tag: "Margin"; + value: Dimensions; +} +/** Inner spacing. */ + | { + tag: "Padding"; + value: Dimensions; +} +/** Background fill. */ + | { + tag: "Background"; + value: Background; +} +/** Border style. */ + | { + tag: "Border"; + value: BorderStyle; +} +/** Fixed height. */ + | { + tag: "Height"; + value: { + height: Size; + }; +} +/** Fixed width. */ + | { + tag: "Width"; + value: { + width: Size; + }; +} +/** Minimum width. */ + | { + tag: "MinWidth"; + value: { + width: Size; + }; +} +/** Minimum height. */ + | { + tag: "MinHeight"; + value: { + height: Size; + }; +} +/** Fill available width. */ + | { + tag: "FillWidth"; + value: { + enabled: boolean; + }; +} +/** Fill available height. */ + | { + tag: "FillHeight"; + value: { + enabled: boolean; + }; +}; +export const Modifier: Codec; +/** Opaque identifier for a push notification, unique per product. */ +export type NotificationId = number; +export const NotificationId: Codec; +/** Outcome of starting a chain-head operation. */ +export type OperationStartedResult = +/** The operation was accepted; results arrive as follow events. */ +{ + tag: "Started"; + value: { + operationId: string; + }; +} +/** Too many operations are in progress; retry after some complete. */ + | { + tag: "LimitReached"; + value?: undefined; +}; +export const OperationStartedResult: Codec; +/** An optional boolean with the compact SCALE encoding used by renderer props. */ +export type OptionalBool = boolean | undefined; +export const OptionalBool: Codec; +/** + * Source for a payment top-up operation. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export type PaymentTopUpSource = +/** Fund from one of the calling product's scoped accounts. */ +{ + tag: "ProductAccount"; + value: { + derivationIndex: DerivationIndex; + }; +} +/** + * Fund from a one-time account represented by its private key. This is a + * standard account holding public funds, not a coin key. + */ + | { + tag: "PrivateKey"; + value: { + sr25519SecretKey: HexString; + }; +} +/** + * Fund directly from coin secret keys. Each key is an sr25519 secret + * controlling a single coin. + */ + | { + tag: "Coins"; + value: { + sr25519SecretKeys: Array; + }; +}; +export const PaymentTopUpSource: Codec; +/** Preimage submission error. */ +export type PreimageSubmitError = +/** Catch-all. */ +{ + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const PreimageSubmitError: Codec; +/** A product account: public key only, no display name. */ +export interface ProductAccount { + /** The account public key (variable-length bytes). */ + publicKey: HexString; +} +export const ProductAccount: Codec; +/** + * Identifies a product-specific account by combining a dotNS domain name with a + * derivation index. + */ +export interface ProductAccountId { + /** A dotNS domain name identifier (e.g., `"my-product.dot"`). */ + dotNsIdentifier: string; + /** Account selector within the product subtree. */ + derivationIndex: DerivationIndex; +} +export const ProductAccountId: Codec; +/** + * Transaction payload for a product account. + * + * Contains everything the host needs to construct a signed extrinsic. + * The signer is a [`ProductAccountId`]; the host resolves the + * corresponding key pair through its account management layer. + */ +export interface ProductAccountTxPayload { + /** Product account that will sign the transaction. */ + signer: ProductAccountId; + /** Chain where the transaction will execute. */ + genesisHash: GenesisHash; + /** SCALE-encoded Call data. */ + callData: HexString; + /** Transaction extensions supplied by the caller. */ + extensions: Array; + /** 0 for Extrinsic V4, runtime-supported value for V5. */ + txExtVersion: number; +} +export const ProductAccountTxPayload: Codec; +/** Versioned envelope for [`ProductChatCustomMessageRenderItem`]. */ +export type VersionedProductChatCustomMessageRenderItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: CustomRendererNode; +}; +export const VersionedProductChatCustomMessageRenderItem: Codec; +/** Versioned envelope for [`ProductChatCustomMessageRenderRequest`]. */ +export type VersionedProductChatCustomMessageRenderRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: ProductChatCustomMessageRenderRequest; +}; +export const VersionedProductChatCustomMessageRenderRequest: Codec; +/** + * A product-scoped proof context: a product and a context within it. + * + * Hashed (with a `product//` prefix) into the 32-byte context bound + * to a ring VRF proof, so contexts cannot collide across products and the same + * member key under different contexts yields unlinkable aliases. + */ +export interface ProductProofContext { + /** dotNS product identifier (e.g. `"my-product.dot"`) scoping the context. */ + productId: string; + /** + * Selector distinguishing contexts within the product; expands to the + * same 32-byte derivation index as [`ProductAccountId::derivation_index`]. + */ + suffix: DerivationIndex; +} +export const ProductProofContext: Codec; +/** Raw data to sign -- either binary bytes or a string message. */ +export type RawPayload = +/** Raw binary data to sign. */ +{ + tag: "Bytes"; + value: { + bytes: HexString; + }; +} +/** String message to sign. */ + | { + tag: "Payload"; + value: { + payload: string; + }; +}; +export const RawPayload: Codec; +/** A registered ring-VRF key entry. */ +export interface RegisteredRingVrfKey { + /** Stable public name of the key. */ + handle: ProductAccountId; + /** Rings the owning product declared this key for. */ + rings: Array; + /** Present when the caller owns the key or requested/granted disclosure. */ + publicKey?: RingVrfPublicKey; +} +export const RegisteredRingVrfKey: Codec; +/** Versioned envelope for [`RemoteChainHeadBodyError`]. */ +export type VersionedRemoteChainHeadBodyError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainHeadBodyError: Codec; +/** Versioned envelope for [`RemoteChainHeadBodyRequest`]. */ +export type VersionedRemoteChainHeadBodyRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadBodyRequest; +}; +export const VersionedRemoteChainHeadBodyRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadBodyResponse`]. */ +export type VersionedRemoteChainHeadBodyResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadBodyResponse; +}; +export const VersionedRemoteChainHeadBodyResponse: Codec; +/** Versioned envelope for [`RemoteChainHeadCallError`]. */ +export type VersionedRemoteChainHeadCallError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainHeadCallError: Codec; +/** Versioned envelope for [`RemoteChainHeadCallRequest`]. */ +export type VersionedRemoteChainHeadCallRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadCallRequest; +}; +export const VersionedRemoteChainHeadCallRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadCallResponse`]. */ +export type VersionedRemoteChainHeadCallResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadCallResponse; +}; +export const VersionedRemoteChainHeadCallResponse: Codec; +/** Versioned envelope for [`RemoteChainHeadContinueError`]. */ +export type VersionedRemoteChainHeadContinueError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainHeadContinueError: Codec; +/** Versioned envelope for [`RemoteChainHeadContinueRequest`]. */ +export type VersionedRemoteChainHeadContinueRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadContinueRequest; +}; +export const VersionedRemoteChainHeadContinueRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadContinueResponse`]. */ +export type VersionedRemoteChainHeadContinueResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedRemoteChainHeadContinueResponse: Codec; +/** Versioned envelope for [`RemoteChainHeadFollowItem`]. */ +export type VersionedRemoteChainHeadFollowItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadFollowItem; +}; +export const VersionedRemoteChainHeadFollowItem: Codec; +/** Versioned envelope for [`RemoteChainHeadFollowRequest`]. */ +export type VersionedRemoteChainHeadFollowRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadFollowRequest; +}; +export const VersionedRemoteChainHeadFollowRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadHeaderError`]. */ +export type VersionedRemoteChainHeadHeaderError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainHeadHeaderError: Codec; +/** Versioned envelope for [`RemoteChainHeadHeaderRequest`]. */ +export type VersionedRemoteChainHeadHeaderRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadHeaderRequest; +}; +export const VersionedRemoteChainHeadHeaderRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadHeaderResponse`]. */ +export type VersionedRemoteChainHeadHeaderResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadHeaderResponse; +}; +export const VersionedRemoteChainHeadHeaderResponse: Codec; +/** Versioned envelope for [`RemoteChainHeadStopOperationError`]. */ +export type VersionedRemoteChainHeadStopOperationError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainHeadStopOperationError: Codec; +/** Versioned envelope for [`RemoteChainHeadStopOperationRequest`]. */ +export type VersionedRemoteChainHeadStopOperationRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadStopOperationRequest; +}; +export const VersionedRemoteChainHeadStopOperationRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadStopOperationResponse`]. */ +export type VersionedRemoteChainHeadStopOperationResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedRemoteChainHeadStopOperationResponse: Codec; +/** Versioned envelope for [`RemoteChainHeadStorageError`]. */ +export type VersionedRemoteChainHeadStorageError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainHeadStorageError: Codec; +/** Versioned envelope for [`RemoteChainHeadStorageRequest`]. */ +export type VersionedRemoteChainHeadStorageRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadStorageRequest; +}; +export const VersionedRemoteChainHeadStorageRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadStorageResponse`]. */ +export type VersionedRemoteChainHeadStorageResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadStorageResponse; +}; +export const VersionedRemoteChainHeadStorageResponse: Codec; +/** Versioned envelope for [`RemoteChainHeadUnpinError`]. */ +export type VersionedRemoteChainHeadUnpinError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainHeadUnpinError: Codec; +/** Versioned envelope for [`RemoteChainHeadUnpinRequest`]. */ +export type VersionedRemoteChainHeadUnpinRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainHeadUnpinRequest; +}; +export const VersionedRemoteChainHeadUnpinRequest: Codec; +/** Versioned envelope for [`RemoteChainHeadUnpinResponse`]. */ +export type VersionedRemoteChainHeadUnpinResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedRemoteChainHeadUnpinResponse: Codec; +/** Versioned envelope for [`RemoteChainInfoError`]. */ +export type VersionedRemoteChainInfoError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainInfoError; +}; +export const VersionedRemoteChainInfoError: Codec; +/** Versioned envelope for [`RemoteChainInfoRequest`]. */ +export type VersionedRemoteChainInfoRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainInfoRequest; +}; +export const VersionedRemoteChainInfoRequest: Codec; +/** Versioned envelope for [`RemoteChainInfoResponse`]. */ +export type VersionedRemoteChainInfoResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainInfoResponse; +}; +export const VersionedRemoteChainInfoResponse: Codec; +/** Versioned envelope for [`RemoteChainSpecChainNameError`]. */ +export type VersionedRemoteChainSpecChainNameError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainSpecChainNameError: Codec; +/** Versioned envelope for [`RemoteChainSpecChainNameRequest`]. */ +export type VersionedRemoteChainSpecChainNameRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainSpecChainNameRequest; +}; +export const VersionedRemoteChainSpecChainNameRequest: Codec; +/** Versioned envelope for [`RemoteChainSpecChainNameResponse`]. */ +export type VersionedRemoteChainSpecChainNameResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainSpecChainNameResponse; +}; +export const VersionedRemoteChainSpecChainNameResponse: Codec; +/** Versioned envelope for [`RemoteChainSpecGenesisHashError`]. */ +export type VersionedRemoteChainSpecGenesisHashError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainSpecGenesisHashError: Codec; +/** Versioned envelope for [`RemoteChainSpecGenesisHashRequest`]. */ +export type VersionedRemoteChainSpecGenesisHashRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainSpecGenesisHashRequest; +}; +export const VersionedRemoteChainSpecGenesisHashRequest: Codec; +/** Versioned envelope for [`RemoteChainSpecGenesisHashResponse`]. */ +export type VersionedRemoteChainSpecGenesisHashResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainSpecGenesisHashResponse; +}; +export const VersionedRemoteChainSpecGenesisHashResponse: Codec; +/** Versioned envelope for [`RemoteChainSpecPropertiesError`]. */ +export type VersionedRemoteChainSpecPropertiesError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainSpecPropertiesError: Codec; +/** Versioned envelope for [`RemoteChainSpecPropertiesRequest`]. */ +export type VersionedRemoteChainSpecPropertiesRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainSpecPropertiesRequest; +}; +export const VersionedRemoteChainSpecPropertiesRequest: Codec; +/** Versioned envelope for [`RemoteChainSpecPropertiesResponse`]. */ +export type VersionedRemoteChainSpecPropertiesResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainSpecPropertiesResponse; +}; +export const VersionedRemoteChainSpecPropertiesResponse: Codec; +/** Versioned envelope for [`RemoteChainTransactionBroadcastError`]. */ +export type VersionedRemoteChainTransactionBroadcastError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainTransactionBroadcastError: Codec; +/** Versioned envelope for [`RemoteChainTransactionBroadcastRequest`]. */ +export type VersionedRemoteChainTransactionBroadcastRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainTransactionBroadcastRequest; +}; +export const VersionedRemoteChainTransactionBroadcastRequest: Codec; +/** Versioned envelope for [`RemoteChainTransactionBroadcastResponse`]. */ +export type VersionedRemoteChainTransactionBroadcastResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainTransactionBroadcastResponse; +}; +export const VersionedRemoteChainTransactionBroadcastResponse: Codec; +/** Versioned envelope for [`RemoteChainTransactionStopError`]. */ +export type VersionedRemoteChainTransactionStopError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteChainTransactionStopError: Codec; +/** Versioned envelope for [`RemoteChainTransactionStopRequest`]. */ +export type VersionedRemoteChainTransactionStopRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteChainTransactionStopRequest; +}; +export const VersionedRemoteChainTransactionStopRequest: Codec; +/** Versioned envelope for [`RemoteChainTransactionStopResponse`]. */ +export type VersionedRemoteChainTransactionStopResponse = +/** Version 1 (no payload). */ +{ + tag: "V1"; + value?: undefined; +}; +export const VersionedRemoteChainTransactionStopResponse: Codec; +/** + * One remote-operation permission requested by the product (RFC 0002). + * + * `ChainSubmit`, `PreimageSubmit`, and `StatementSubmit` are also triggered + * implicitly by the corresponding business calls when not yet granted. + */ +export type RemotePermission = +/** + * Reaching a set of domains: outbound HTTP/WebSocket access, and sending + * the user out to one of them with `navigate_to`. + * + * One grant per host covers both, because both hand the same third party + * the same thing: that the user is here, and whatever the product puts in + * the URL. Splitting them would put the same question to the user twice. + */ +{ + tag: "Remote"; + value: { + domains: Array; + }; +} +/** + * WebRTC access. + * + * Enforced inside the product's own realm rather than at a network layer: + * ICE reaches an arbitrary host over UDP, so no content rule list, request + * interceptor, or CSP directive observes it. A host peeks this decision + * before the product realm exists and the lockdown container removes + * `RTCPeerConnection` — and its vendor-prefixed aliases — unless the answer + * was an explicit grant. Resolving it up front is what makes the gate + * unforgeable, and it means a fresh grant applies from the next load. + * + * Camera and microphone capture is gated by the OS permission prompts and + * [`HostDevicePermissionRequest`], not by this permission. + */ + | { + tag: "WebRtc"; + value?: undefined; +} +/** Submitting transactions on behalf of the user via `remote_chain_transaction_broadcast`. */ + | { + tag: "ChainSubmit"; + value?: undefined; +} +/** Submitting preimages on behalf of the user via `remote_preimage_submit`. */ + | { + tag: "PreimageSubmit"; + value?: undefined; +} +/** Submitting statements on behalf of the user via `remote_statement_store_submit`. */ + | { + tag: "StatementSubmit"; + value?: undefined; +}; +export const RemotePermission: Codec; +/** Versioned envelope for [`RemotePermissionError`]. */ +export type VersionedRemotePermissionError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemotePermissionError: Codec; +/** Versioned envelope for [`RemotePermissionRequest`]. */ +export type VersionedRemotePermissionRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemotePermissionRequest; +}; +export const VersionedRemotePermissionRequest: Codec; +/** Versioned envelope for [`RemotePermissionResponse`]. */ +export type VersionedRemotePermissionResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemotePermissionResponse; +}; +export const VersionedRemotePermissionResponse: Codec; +/** Versioned envelope for [`RemotePreimageLookupSubscribeItem`]. */ +export type VersionedRemotePreimageLookupSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemotePreimageLookupSubscribeItem; +}; +export const VersionedRemotePreimageLookupSubscribeItem: Codec; +/** Versioned envelope for [`RemotePreimageLookupSubscribeRequest`]. */ +export type VersionedRemotePreimageLookupSubscribeRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemotePreimageLookupSubscribeRequest; +}; +export const VersionedRemotePreimageLookupSubscribeRequest: Codec; +/** Versioned envelope for [`RemotePreimageSubmitError`]. */ +export type VersionedRemotePreimageSubmitError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: PreimageSubmitError; +}; +export const VersionedRemotePreimageSubmitError: Codec; +/** Versioned envelope for [`RemotePreimageSubmitRequest`]. */ +export type VersionedRemotePreimageSubmitRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HexString; +}; +export const VersionedRemotePreimageSubmitRequest: Codec; +/** Versioned envelope for [`RemotePreimageSubmitResponse`]. */ +export type VersionedRemotePreimageSubmitResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: HexString; +}; +export const VersionedRemotePreimageSubmitResponse: Codec; +/** Versioned envelope for [`RemoteStatementStoreCreateProofAuthorizedError`]. */ +export type VersionedRemoteStatementStoreCreateProofAuthorizedError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteStatementStoreCreateProofError; +}; +export const VersionedRemoteStatementStoreCreateProofAuthorizedError: Codec; +/** Versioned envelope for [`RemoteStatementStoreCreateProofAuthorizedRequest`]. */ +export type VersionedRemoteStatementStoreCreateProofAuthorizedRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: Statement; +}; +export const VersionedRemoteStatementStoreCreateProofAuthorizedRequest: Codec; +/** Versioned envelope for [`RemoteStatementStoreCreateProofAuthorizedResponse`]. */ +export type VersionedRemoteStatementStoreCreateProofAuthorizedResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteStatementStoreCreateProofResponse; +}; +export const VersionedRemoteStatementStoreCreateProofAuthorizedResponse: Codec; +/** Versioned envelope for [`RemoteStatementStoreCreateProofError`]. */ +export type VersionedRemoteStatementStoreCreateProofError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteStatementStoreCreateProofError; +}; +export const VersionedRemoteStatementStoreCreateProofError: Codec; +/** Versioned envelope for [`RemoteStatementStoreCreateProofRequest`]. */ +export type VersionedRemoteStatementStoreCreateProofRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteStatementStoreCreateProofRequest; +}; +export const VersionedRemoteStatementStoreCreateProofRequest: Codec; +/** Versioned envelope for [`RemoteStatementStoreCreateProofResponse`]. */ +export type VersionedRemoteStatementStoreCreateProofResponse = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteStatementStoreCreateProofResponse; +}; +export const VersionedRemoteStatementStoreCreateProofResponse: Codec; +/** Versioned envelope for [`RemoteStatementStoreSubmitError`]. */ +export type VersionedRemoteStatementStoreSubmitError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteStatementStoreSubmitError: Codec; +/** Versioned envelope for [`RemoteStatementStoreSubmitRequest`]. */ +export type VersionedRemoteStatementStoreSubmitRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: SignedStatement; +}; +export const VersionedRemoteStatementStoreSubmitRequest: Codec; +/** Versioned envelope for [`RemoteStatementStoreSubscribeError`]. */ +export type VersionedRemoteStatementStoreSubscribeError = +/** Version 1 payload. */ +{ + tag: "V1"; + value: GenericError; +}; +export const VersionedRemoteStatementStoreSubscribeError: Codec; +/** Versioned envelope for [`RemoteStatementStoreSubscribeItem`]. */ +export type VersionedRemoteStatementStoreSubscribeItem = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteStatementStoreSubscribeItem; +}; +export const VersionedRemoteStatementStoreSubscribeItem: Codec; +/** Versioned envelope for [`RemoteStatementStoreSubscribeRequest`]. */ +export type VersionedRemoteStatementStoreSubscribeRequest = +/** Version 1 payload. */ +{ + tag: "V1"; + value: RemoteStatementStoreSubscribeRequest; +}; +export const VersionedRemoteStatementStoreSubscribeRequest: Codec; +/** Error from [`crate::api::ResourceAllocation::request`]. */ +export type ResourceAllocationError = +/** Catch-all. */ +{ + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const ResourceAllocationError: Codec; +/** + * Locates a ring for ring VRF operations using only identifiers that are + * stable across membership changes. + */ +export interface RingLocation { + /** Genesis hash of the chain hosting the ring. */ + chainId: GenesisHash; + /** Path addressing the ring within the chain. */ + junctions: Array; +} +export const RingLocation: Codec; +/** A single step in a [`RingLocation`] path, addressing a ring within a chain. */ +export type RingLocationJunction = +/** Pallet instance hosting the ring collection. */ +{ + tag: "PalletInstance"; + value: number; +} +/** Ring collection identifier within the pallet. */ + | { + tag: "CollectionId"; + value: HexString; +}; +export const RingLocationJunction: Codec; +/** How much of a registry entry the caller asks for. */ +export type RingVrfKeyDisclosure = "Anonymized" | "PublicKey"; +export const RingVrfKeyDisclosure: Codec; +/** Ring-VRF member public key. */ +export type RingVrfPublicKey = HexString; +export const RingVrfPublicKey: Codec; +/** Properties for a [`CustomRendererNode::Row`] layout. */ +export interface RowProps { + /** Vertical alignment of children. */ + verticalAlignment?: VerticalAlignment; + /** Horizontal arrangement of children. */ + horizontalArrangement?: Arrangement; +} +export const RowProps: Codec; +/** One entry of a runtime's supported API list. */ +export interface RuntimeApi { + /** Runtime API name. */ + name: string; + /** Runtime API version. */ + version: number; +} +export const RuntimeApi: Codec; +/** Runtime version information for a block's runtime. */ +export interface RuntimeSpec { + /** Specification name. */ + specName: string; + /** Implementation name. */ + implName: string; + /** Spec version number. */ + specVersion: number; + /** Implementation version. */ + implVersion: number; + /** Transaction format version. */ + transactionVersion?: number; + /** Supported runtime APIs. */ + apis: Array; +} +export const RuntimeSpec: Codec; +/** Runtime attached to follow events, either a decoded spec or a decode error. */ +export type RuntimeType = +/** Runtime spec decoded successfully. */ +{ + tag: "Valid"; + value: RuntimeSpec; +} +/** The runtime could not be decoded. */ + | { + tag: "Invalid"; + value: { + error: string; + }; +}; +export const RuntimeType: Codec; +/** Shape for borders and backgrounds. */ +export type Shape = +/** Border radius value. */ +{ + tag: "Rounded"; + value: { + radius: Size; + }; +} +/** Circular shape. */ + | { + tag: "Circle"; + value?: undefined; +}; +export const Shape: Codec; +/** A statement with a required (not optional) proof. */ +export interface SignedStatement { + /** Required cryptographic proof. */ + proof: StatementProof; + /** Optional decryption key. */ + decryptionKey?: HexString; + /** Optional Unix timestamp expiry. */ + expiry?: bigint; + /** Optional channel. */ + channel?: HexString; + /** [u8; 32] tags. */ + topics: Array; + /** Optional data payload. */ + data?: HexString; +} +export const SignedStatement: Codec; +/** + * A size/dimension value (logical pixels) used across the custom renderer. + * + * Encoded as a SCALE `Compact`: the common small values cost a single + * byte on the wire instead of eight. + */ +export type Size = number | bigint; +export const Size: Codec; +/** A statement with optional proof and metadata. */ +export interface Statement { + /** Optional cryptographic proof. */ + proof?: StatementProof; + /** Optional decryption key. */ + decryptionKey?: HexString; + /** Optional Unix timestamp expiry. */ + expiry?: bigint; + /** Optional channel. */ + channel?: HexString; + /** [u8; 32] tags. */ + topics: Array; + /** Optional data payload. */ + data?: HexString; +} +export const Statement: Codec; +/** Cryptographic proof for a statement. */ +export type StatementProof = +/** Sr25519 signature proof. */ +{ + tag: "Sr25519"; + value: { + signature: HexString; + signer: HexString; + }; +} +/** Ed25519 signature proof. */ + | { + tag: "Ed25519"; + value: { + signature: HexString; + signer: HexString; + }; +} +/** ECDSA signature proof. */ + | { + tag: "Ecdsa"; + value: { + signature: HexString; + signer: HexString; + }; +} +/** On-chain event proof. */ + | { + tag: "OnChain"; + value: { + who: HexString; + blockHash: HexString; + event: bigint; + }; +}; +export const StatementProof: Codec; +/** A single key query within a chain-head storage request. */ +export interface StorageQueryItem { + /** Storage key to query. */ + key: HexString; + /** What to return. */ + queryType: StorageQueryType; +} +export const StorageQueryItem: Codec; +/** What a chain-head storage query returns for a key. */ +export type StorageQueryType = "Value" | "Hash" | "ClosestDescendantMerkleValue" | "DescendantsValues" | "DescendantsHashes"; +export const StorageQueryType: Codec; +/** Result for one queried storage key. */ +export interface StorageResultItem { + /** The queried key. */ + key: HexString; + /** Value, if requested. */ + value?: HexString; + /** Hash, if requested. */ + hash?: HexString; + /** Merkle value, if requested. */ + closestDescendantMerkleValue?: HexString; +} +export const StorageResultItem: Codec; +/** Properties for a [`CustomRendererNode::TextField`]. */ +export interface TextFieldProps { + /** Current text value. */ + text: string; + /** Placeholder text. */ + placeholder?: string; + /** Field label. */ + label?: string; + /** Whether the field is enabled. Absent leaves the default to the host. */ + enabled: OptionalBool; + /** Action identifier triggered when the value changes. */ + valueChangeAction?: string; +} +export const TextFieldProps: Codec; +/** Properties for a [`CustomRendererNode::Text`] display. */ +export interface TextProps { + /** Typography preset. */ + style?: TypographyStyle; + /** Text color. */ + color?: ColorToken; +} +export const TextProps: Codec; +/** Identifies a named theme. */ +export type ThemeName = +/** A custom named theme. */ +{ + tag: "Custom"; + value: string; +} +/** The host's default theme. */ + | { + tag: "Default"; + value?: undefined; +}; +export const ThemeName: Codec; +/** Light or dark variant. */ +export type ThemeVariant = "Light" | "Dark"; +export const ThemeVariant: Codec; +/** 32-byte statement topic. */ +export type Topic = HexString; +export const Topic: Codec; +/** A signed extension for a transaction payload. */ +export interface TxPayloadExtension { + /** Extension name (e.g., `"CheckSpecVersion"`). */ + id: string; + /** SCALE-encoded extra data (in extrinsic body). */ + extra: HexString; + /** SCALE-encoded implicit data (signed, not in body). */ + additionalSigned: HexString; +} +export const TxPayloadExtension: Codec; +/** Text typography presets. */ +export type TypographyStyle = "HeadlineLarge" | "TitleMediumRegular" | "BodyLargeRegular" | "BodyMediumRegular" | "BodySmallRegular"; +export const TypographyStyle: Codec; +/** User's authentication state. */ +export type HostAccountConnectionStatusSubscribeItem = "Disconnected" | "Connected"; +export const HostAccountConnectionStatusSubscribeItem: Codec; +/** Error returned when ring VRF proof creation fails. */ +export type HostAccountCreateProofError = +/** Ring not available at the specified location. */ +{ + tag: "RingNotFound"; + value?: undefined; +} +/** The registered member key is not a member of the requested ring. */ + | { + tag: "NotMember"; + value?: undefined; +} +/** The key handle is not registered. */ + | { + tag: "KeyNotRegistered"; + value?: undefined; +} +/** The key handle is not registered for the requested ring. */ + | { + tag: "KeyNotInRing"; + value?: undefined; +} +/** The foreign key owner has not allowlisted the caller. */ + | { + tag: "NotAllowlisted"; + value?: undefined; +} +/** User or host rejected. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostAccountCreateProofError: Codec; +/** Request to create a ring VRF proof. */ +export interface HostAccountCreateProofRequest { + /** Ring-VRF key handle naming the member key to use. */ + keyHandle: ProductAccountId; + /** Product-scoped context the derived alias is bound to. */ + context: ProductProofContext; + /** Ring to generate the proof against. */ + ringLocation: RingLocation; + /** Opaque message bound into the proof. */ + message: HexString; +} +export const HostAccountCreateProofRequest: Codec; +/** + * Response containing a ring VRF proof and the values needed to verify it + * against a downstream precompile. + */ +export interface HostAccountCreateProofResponse { + /** Variable-length ring VRF proof bytes. */ + proof: HexString; + /** Alias derived for the request's context. */ + contextualAlias: ContextualAlias; + /** Index of the selected member key within the ring. */ + ringIndex: number; + /** Ring revision the proof was generated against. */ + ringRevision: number; +} +export const HostAccountCreateProofResponse: Codec; +/** Error returned when contextual alias derivation fails. */ +export type HostAccountGetAliasError = +/** Ring not available at the specified location. */ +{ + tag: "RingNotFound"; + value?: undefined; +} +/** The registered member key is not a member of the requested ring. */ + | { + tag: "NotMember"; + value?: undefined; +} +/** The key handle is not registered. */ + | { + tag: "KeyNotRegistered"; + value?: undefined; +} +/** The key handle is not registered for the requested ring. */ + | { + tag: "KeyNotInRing"; + value?: undefined; +} +/** User or host rejected. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostAccountGetAliasError: Codec; +/** Request to retrieve the contextual alias for a context and ring. */ +export interface HostAccountGetAliasRequest { + /** Ring-VRF key handle naming the member key to use. */ + keyHandle: ProductAccountId; + /** Product-scoped context to derive the alias for. */ + context: ProductProofContext; + /** Ring whose member key the host should use; matches `create_proof`. */ + ringLocation: RingLocation; +} +export const HostAccountGetAliasRequest: Codec; +/** Error returned when credential/account requests fail. */ +export type HostAccountGetError = +/** User is not logged in. */ +{ + tag: "NotConnected"; + value?: undefined; +} +/** User or host rejected the request. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Domain identifier is invalid. */ + | { + tag: "DomainNotValid"; + value?: undefined; +} +/** Catch-all error with reason. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostAccountGetError: Codec; +/** Request to retrieve a product-scoped account. */ +export interface HostAccountGetRequest { + /** Product account to retrieve. */ + productAccountId: ProductAccountId; +} +export const HostAccountGetRequest: Codec; +/** Response containing a product-scoped account. */ +export interface HostAccountGetResponse { + /** Retrieved product account. */ + account: ProductAccount; +} +export const HostAccountGetResponse: Codec; +/** Error returned when listing ring-VRF keys fails. */ +export type HostAccountListRingVrfKeysError = +/** User is not logged in. */ +{ + tag: "NotConnected"; + value?: undefined; +} +/** User or host rejected. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostAccountListRingVrfKeysError: Codec; +/** Request to list registered ring-VRF keys for an owner product. */ +export interface HostAccountListRingVrfKeysRequest { + /** Product whose registry entries should be listed. */ + owner: string; + /** Disclosure level requested by the caller. */ + disclosure: RingVrfKeyDisclosure; +} +export const HostAccountListRingVrfKeysRequest: Codec; +/** Error returned when ring-VRF key registration fails. */ +export type HostAccountRegisterRingVrfKeyError = +/** User is not logged in. */ +{ + tag: "NotConnected"; + value?: undefined; +} +/** Ring not available at the specified location. */ + | { + tag: "RingNotFound"; + value?: undefined; +} +/** User or host rejected. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostAccountRegisterRingVrfKeyError: Codec; +/** Request to register a ring-VRF key owned by the calling product. */ +export interface HostAccountRegisterRingVrfKeyRequest { + /** Key derivation index within the caller's ring-VRF domain. */ + index: DerivationIndex; + /** Ring this key is declared for. */ + ring: RingLocation; +} +export const HostAccountRegisterRingVrfKeyRequest: Codec; +/** Error returned when direct ring-VRF key signing fails. */ +export type HostAccountRingVrfSignError = +/** User is not logged in. */ +{ + tag: "NotConnected"; + value?: undefined; +} +/** The key handle is not registered. */ + | { + tag: "KeyNotRegistered"; + value?: undefined; +} +/** The foreign key owner has not allowlisted the caller. */ + | { + tag: "NotAllowlisted"; + value?: undefined; +} +/** User or host rejected. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostAccountRingVrfSignError: Codec; +/** Request to sign bytes with a registered ring-VRF key. */ +export interface HostAccountRingVrfSignRequest { + /** Registered key handle. */ + keyHandle: ProductAccountId; + /** Opaque message to sign. */ + message: HexString; +} +export const HostAccountRingVrfSignRequest: Codec; +/** Error returned when VRF signing fails. */ +export type HostAccountSignVrfError = +/** User is not logged in. */ +{ + tag: "NotConnected"; + value?: undefined; +} +/** User or host rejected the signing confirmation. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostAccountSignVrfError: Codec; +/** + * Request to produce an sr25519 VRF signature from a product account over a + * caller-supplied Merlin transcript. + */ +export interface HostAccountSignVrfRequest { + /** Account whose key signs the VRF. */ + account: ProductAccountId; + /** Root domain-separation label: `Transcript::new(transcript_label)`. */ + transcriptLabel: HexString; + /** Transcript items replayed in order as `append_message(label, value)`. */ + items: Array; +} +export const HostAccountSignVrfRequest: Codec; +/** A chat action received from the host. */ +export interface HostChatActionSubscribeItem { + /** Room where the action occurred. */ + roomId: string; + /** Peer who initiated the action. */ + peer: string; + /** The action payload. */ + payload: ChatActionPayload; +} +export const HostChatActionSubscribeItem: Codec; +/** Chat room registration error. */ +export type HostChatCreateRoomError = +/** Not allowed. */ +{ + tag: "PermissionDenied"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostChatCreateRoomError: Codec; +/** Request to create a chat room. */ +export interface HostChatCreateRoomRequest { + /** Unique room identifier. */ + roomId: string; + /** Room display name. */ + name: string; + /** URL or base64 image. */ + icon: string; +} +export const HostChatCreateRoomRequest: Codec; +/** Result of a room registration. */ +export interface HostChatCreateRoomResponse { + /** `New` or `Exists`. */ + status: ChatRoomRegistrationStatus; +} +export const HostChatCreateRoomResponse: Codec; +/** Item containing the current chat rooms. */ +export interface HostChatListSubscribeItem { + /** Chat rooms the product participates in. */ + rooms: Array; +} +export const HostChatListSubscribeItem: Codec; +/** Chat message posting error. */ +export type HostChatPostMessageError = +/** Message exceeded size limit. */ +{ + tag: "MessageTooLarge"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostChatPostMessageError: Codec; +/** Request to post a message to a chat room. */ +export interface HostChatPostMessageRequest { + /** Room to post to. */ + roomId: string; + /** Message content. */ + payload: ChatMessageContent; +} +export const HostChatPostMessageRequest: Codec; +/** Result of posting a message. */ +export interface HostChatPostMessageResponse { + /** + * Host-assigned message id, and the correlation key for any action the + * message carries: a trigger names it in [`ActionTrigger::message_id`]. + */ + messageId: string; +} +export const HostChatPostMessageResponse: Codec; +/** Chat bot registration error. */ +export type HostChatRegisterBotError = +/** Not allowed. */ +{ + tag: "PermissionDenied"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostChatRegisterBotError: Codec; +/** Request to register a chat bot. */ +export interface HostChatRegisterBotRequest { + /** Unique bot identifier. */ + botId: string; + /** Bot display name. */ + name: string; + /** URL or base64 image. */ + icon: string; +} +export const HostChatRegisterBotRequest: Codec; +/** Result of a bot registration. */ +export interface HostChatRegisterBotResponse { + /** `New` or `Exists`. */ + status: ChatBotRegistrationStatus; +} +export const HostChatRegisterBotResponse: Codec; +/** Request to create a cheque from a local purse to a receivable. */ +export interface HostCoinPaymentCreateChequeRequest { + /** Source purse. */ + from: CoinPaymentPurseId; + /** Destination receivable. */ + to: CoinPaymentReceivable; + /** Payment amount. */ + amount: CoinPaymentBalance; +} +export const HostCoinPaymentCreateChequeRequest: Codec; +/** Created cheque response. */ +export interface HostCoinPaymentCreateChequeResponse { + /** Encrypted cheque. */ + cheque: CoinPaymentCheque; +} +export const HostCoinPaymentCreateChequeResponse: Codec; +/** Request to create a new firewalled CoinPayment purse. */ +export interface HostCoinPaymentCreatePurseRequest { + /** Human-readable purse name. */ + name: string; +} +export const HostCoinPaymentCreatePurseRequest: Codec; +/** Created purse identifier. */ +export interface HostCoinPaymentCreatePurseResponse { + /** Assigned purse identifier. */ + purse: CoinPaymentPurseId; +} +export const HostCoinPaymentCreatePurseResponse: Codec; +/** Request to create a fresh receivable for a purse. */ +export interface HostCoinPaymentCreateReceivableRequest { + /** Target purse for future deposits. */ + into: CoinPaymentPurseId; +} +export const HostCoinPaymentCreateReceivableRequest: Codec; +/** Created receivable response. */ +export interface HostCoinPaymentCreateReceivableResponse { + /** Receivable public key. */ + receivable: CoinPaymentReceivable; +} +export const HostCoinPaymentCreateReceivableResponse: Codec; +/** Request to delete a purse after draining its balance. */ +export interface HostCoinPaymentDeletePurseRequest { + /** Purse to delete. */ + target: CoinPaymentPurseId; + /** Purse that receives drained funds. */ + drainInto: CoinPaymentPurseId; +} +export const HostCoinPaymentDeletePurseRequest: Codec; +/** Request to deposit a cheque into the purse associated with its receivable. */ +export interface HostCoinPaymentDepositRequest { + /** Cheque to deposit. */ + cheque: CoinPaymentCheque; +} +export const HostCoinPaymentDepositRequest: Codec; +/** Stream item for `host_coin_payment_listen_for`. */ +export type HostCoinPaymentListenForItem = +/** Handoff channel suitable for inclusion in an invoice. */ +{ + tag: "Channel"; + value: CoinPaymentTransmissionChannel; +} +/** Cheque received through the handoff channel. */ + | { + tag: "Cheque"; + value: CoinPaymentCheque; +}; +export const HostCoinPaymentListenForItem: Codec; +/** Request to listen for a cheque delivered to a receivable. */ +export interface HostCoinPaymentListenForRequest { + /** Receivable to listen for. */ + receivable: CoinPaymentReceivable; +} +export const HostCoinPaymentListenForRequest: Codec; +/** Request to query product-visible purse metadata. */ +export interface HostCoinPaymentQueryPurseRequest { + /** Purse to query. */ + purse: CoinPaymentPurseId; +} +export const HostCoinPaymentQueryPurseRequest: Codec; +/** Product-visible purse metadata response. */ +export interface HostCoinPaymentQueryPurseResponse { + /** Purse information. */ + info: CoinPaymentPurseInfo; +} +export const HostCoinPaymentQueryPurseResponse: Codec; +/** Request to transfer balance between local purses. */ +export interface HostCoinPaymentRebalancePurseRequest { + /** Source purse. */ + from: CoinPaymentPurseId; + /** Destination purse. */ + to: CoinPaymentPurseId; + /** Amount to move. */ + amount: CoinPaymentBalance; +} +export const HostCoinPaymentRebalancePurseRequest: Codec; +/** Request to refund coins associated with a receivable. */ +export interface HostCoinPaymentRefundRequest { + /** Receivable to refund. */ + receivable: CoinPaymentReceivable; +} +export const HostCoinPaymentRefundRequest: Codec; +/** Transaction creation error. */ +export type HostCreateTransactionError = +/** Payload could not be deserialized. */ +{ + tag: "FailedToDecode"; + value?: undefined; +} +/** User rejected. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Unsupported payload version or extension. */ + | { + tag: "NotSupported"; + value: { + reason: string; + }; +} +/** Not authenticated. */ + | { + tag: "PermissionDenied"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostCreateTransactionError: Codec; +/** Response containing a created transaction. */ +export interface HostCreateTransactionResponse { + /** + * SCALE-encoded transaction, signed unless the request supplied its own + * V5 `VerifyMultiSignature` extension. + */ + transaction: HexString; +} +export const HostCreateTransactionResponse: Codec; +/** Response containing a transaction created with a non-product account. */ +export interface HostCreateTransactionWithLegacyAccountResponse { + /** + * SCALE-encoded transaction, signed unless the request supplied its own + * V5 `VerifyMultiSignature` extension. + */ + transaction: HexString; +} +export const HostCreateTransactionWithLegacyAccountResponse: Codec; +/** Error from [`crate::api::Entropy::derive`] (RFC 0007). */ +export type HostDeriveEntropyError = +/** Catch-all. */ +{ + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostDeriveEntropyError: Codec; +/** + * Request to derive deterministic per-product entropy (RFC 0007). + * + * The host derives 32 bytes from product-scoped seed material and `context`. + * Repeated calls with the same `context` for the same product yield the same + * entropy. + */ +export interface HostDeriveEntropyRequest { + /** Domain-separated derivation context. */ + context: HexString; +} +export const HostDeriveEntropyRequest: Codec; +/** Response carrying 32 bytes of deterministically derived entropy. */ +export interface HostDeriveEntropyResponse { + /** 32 bytes of derived entropy. */ + entropy: HexString; +} +export const HostDeriveEntropyResponse: Codec; +/** + * Device-capability permission requested from the host (RFC 0002). + * + * The user's decision is persisted indefinitely after the first prompt and + * survives app restarts, whether the decision was grant or deny; the host + * does not re-prompt on subsequent requests for the same capability. + * + * That decision is about this product. The OS grant behind it belongs to the + * host application and can move independently, so a host that can read OS + * state has the capability resolve only while both allow it: a stored grant + * whose OS grant was revoked answers `granted: false` without a prompt. An OS + * grant that is merely undetermined does not change the answer, because the OS + * resolves its own gate when the capability is used. + */ +export type HostDevicePermissionRequest = "Notifications" | "Camera" | "Microphone" | "Bluetooth" | "NFC" | "Location" | "Clipboard" | "OpenUrl" | "Biometrics"; +export const HostDevicePermissionRequest: Codec; +/** Outcome of a device-permission request. */ +export interface HostDevicePermissionResponse { + /** Whether the permission was granted. */ + granted: boolean; +} +export const HostDevicePermissionResponse: Codec; +/** Request to query whether a feature is supported by the host. */ +export type HostFeatureSupportedRequest = +/** Ask whether the host can interact with the chain identified by genesis hash. */ +{ + tag: "Chain"; + value: { + genesisHash: HexString; + }; +}; +export const HostFeatureSupportedRequest: Codec; +/** Response to a feature-support query. */ +export interface HostFeatureSupportedResponse { + /** Whether the feature is supported. */ + supported: boolean; +} +export const HostFeatureSupportedResponse: Codec; +/** Response containing all legacy (user-imported) accounts owned by the user. */ +export interface HostGetLegacyAccountsResponse { + /** Legacy accounts. */ + accounts: Array; +} +export const HostGetLegacyAccountsResponse: Codec; +/** Response containing the product context bound to the current host runtime. */ +export interface HostGetProductContextResponse { + /** Full canonical identifier used for authorization and account derivation. */ + productId: string; +} +export const HostGetProductContextResponse: Codec; +/** Error from [`crate::api::Account::get_user_id`]. */ +export type HostGetUserIdError = +/** User denied the identity disclosure request. */ +{ + tag: "PermissionDenied"; + value?: undefined; +} +/** User is not logged in. */ + | { + tag: "NotConnected"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostGetUserIdError: Codec; +/** The user's primary DotNS account identity. */ +export interface HostGetUserIdResponse { + /** The user's primary DotNS username. */ + primaryUsername: string; +} +export const HostGetUserIdResponse: Codec; +/** + * Error from [`crate::api::System::handshake`] (RFC 0009). + * + * The handshake is the first call on a fresh connection; it does not require + * user authentication and is used to negotiate the wire codec version. + */ +export type HostHandshakeError = +/** Host did not complete the handshake in time. */ +{ + tag: "Timeout"; + value?: undefined; +} +/** Host does not speak the codec version requested by the product. */ + | { + tag: "UnsupportedProtocolVersion"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: GenericError; +}; +export const HostHandshakeError: Codec; +/** Wire-codec negotiation payload sent by the product (RFC 0009). */ +export interface HostHandshakeRequest { + /** Wire codec version requested by the product. */ + codecVersion: number; +} +export const HostHandshakeRequest: Codec; +/** Request to clear a local storage key. */ +export interface HostLocalStorageClearRequest { + /** Storage key to clear. */ + key: string; +} +export const HostLocalStorageClearRequest: Codec; +/** Local storage operation error. */ +export type HostLocalStorageReadError = +/** Storage quota exceeded. */ +{ + tag: "Full"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostLocalStorageReadError: Codec; +/** Request to read a local storage value. */ +export interface HostLocalStorageReadRequest { + /** Storage key to read. */ + key: string; +} +export const HostLocalStorageReadRequest: Codec; +/** Response containing an optional local storage value. */ +export interface HostLocalStorageReadResponse { + /** Stored value, if present. */ + value?: HexString; +} +export const HostLocalStorageReadResponse: Codec; +/** Request to write a value into local storage. */ +export interface HostLocalStorageWriteRequest { + /** Storage key to write. */ + key: string; + /** Value to store at the key. */ + value: HexString; +} +export const HostLocalStorageWriteRequest: Codec; +/** Error from [`crate::api::System::navigate_to`]. */ +export type HostNavigateToError = +/** + * The target host is not authorized for outbound access: the user answered + * no to the prompt, a stored decision already refused it, or no prompt + * could be put to the user. + */ +{ + tag: "PermissionDenied"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostNavigateToError: Codec; +/** Request to navigate the host to an external URL. */ +export interface HostNavigateToRequest { + /** URL to open. */ + url: string; +} +export const HostNavigateToRequest: Codec; +/** + * Error from [`crate::api::Payment::balance_subscribe`]. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export type HostPaymentBalanceSubscribeError = +/** User denied the balance disclosure request. */ +{ + tag: "PermissionDenied"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostPaymentBalanceSubscribeError: Codec; +/** + * Current payment balance state pushed to subscribers. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export interface HostPaymentBalanceSubscribeItem { + /** Balance that can be spent right now. */ + available: Balance; +} +export const HostPaymentBalanceSubscribeItem: Codec; +/** Request to subscribe to payment balance updates. */ +export interface HostPaymentBalanceSubscribeRequest { + /** Optional purse selector. `None` means MAIN_PURSE. */ + purse?: CoinPaymentPurseId; +} +export const HostPaymentBalanceSubscribeRequest: Codec; +/** + * Error from [`crate::api::Payment::request`]. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export type HostPaymentError = +/** User rejected the payment request. */ +{ + tag: "Rejected"; + value?: undefined; +} +/** User's available balance is not sufficient for the requested amount. */ + | { + tag: "InsufficientBalance"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostPaymentError: Codec; +/** Request to initiate a payment to another account. */ +export interface HostPaymentRequest { + /** Optional purse selector. `None` means MAIN_PURSE. */ + from?: CoinPaymentPurseId; + /** Amount to pay. */ + amount: Balance; + /** Destination account. */ + destination: HexString; +} +export const HostPaymentRequest: Codec; +/** + * Receipt returned after a successful payment request. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export interface HostPaymentResponse { + /** The assigned payment identifier. */ + id: string; +} +export const HostPaymentResponse: Codec; +/** + * Error from [`crate::api::Payment::status_subscribe`]. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export type HostPaymentStatusSubscribeError = +/** Payment ID was not found or does not belong to the current product. */ +{ + tag: "PaymentNotFound"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostPaymentStatusSubscribeError: Codec; +/** + * Payment lifecycle status pushed to subscribers. + * + * Once a terminal state (`Completed` or `Failed`) is reached, the host + * delivers it and may close the subscription. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export type HostPaymentStatusSubscribeItem = +/** Payment is being processed. */ +{ + tag: "Processing"; + value?: undefined; +} +/** Payment has been settled successfully. */ + | { + tag: "Completed"; + value?: undefined; +} +/** Payment has failed. */ + | { + tag: "Failed"; + value: { + reason: string; + }; +}; +export const HostPaymentStatusSubscribeItem: Codec; +/** Request to subscribe to a payment status. */ +export interface HostPaymentStatusSubscribeRequest { + /** Payment identifier to watch. */ + paymentId: string; +} +export const HostPaymentStatusSubscribeRequest: Codec; +/** + * Error from [`crate::api::Payment::top_up`]. + * + * See [RFC 0006]. + * + * [RFC 0006]: https://github.com/paritytech/triangle-js-sdks/pull/94 + */ +export type HostPaymentTopUpError = +/** The source account does not hold sufficient funds. */ +{ + tag: "InsufficientFunds"; + value?: undefined; +} +/** The source account was not found or is invalid. */ + | { + tag: "InvalidSource"; + value?: undefined; +} +/** Some coins were claimed but the total fell short of the requested amount. */ + | { + tag: "PartialPayment"; + value: { + credited: Balance; + }; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostPaymentTopUpError: Codec; +/** Request to top up the product payment balance. */ +export interface HostPaymentTopUpRequest { + /** Optional purse selector. `None` means MAIN_PURSE. */ + into?: CoinPaymentPurseId; + /** Amount to top up. */ + amount: Balance; + /** Funding source for the top-up. */ + source: PaymentTopUpSource; +} +export const HostPaymentTopUpRequest: Codec; +/** Request to cancel a previously scheduled notification. */ +export interface HostPushNotificationCancelRequest { + /** The notification identifier returned by [`HostPushNotificationResponse`]. */ + id: NotificationId; +} +export const HostPushNotificationCancelRequest: Codec; +/** Push notification error. */ +export type HostPushNotificationError = +/** The host-wide queue of pending scheduled notifications is full. */ +{ + tag: "ScheduleLimitReached"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostPushNotificationError: Codec; +/** + * Push notification payload. + * + * When `scheduled_at` is `Some`, the notification is deferred to the given + * wall-clock instant (Unix milliseconds UTC). `None` fires immediately, + * preserving prior behaviour. See [RFC 0019]. + * + * [RFC 0019]: https://github.com/paritytech/host-rust-core/blob/main/docs/rfcs/0019-scheduled-notifications.md + */ +export interface HostPushNotificationRequest { + /** Notification text. */ + text: string; + /** Optional URL to open on tap. */ + deeplink?: string; + /** + * Optional Unix timestamp in milliseconds (UTC) at which the notification + * should fire. `None` fires immediately. + */ + scheduledAt?: bigint; +} +export const HostPushNotificationRequest: Codec; +/** Successful push notification response carrying the assigned id. */ +export interface HostPushNotificationResponse { + /** Host-assigned notification identifier. */ + id: NotificationId; +} +export const HostPushNotificationResponse: Codec; +/** Login request error. */ +export type HostRequestLoginError = +/** Catch-all. */ +{ + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostRequestLoginError: Codec; +/** Request to present the host login flow. */ +export interface HostRequestLoginRequest { + /** Optional human-readable reason shown in the login UI. */ + reason?: string; +} +export const HostRequestLoginRequest: Codec; +/** Result of a login request. */ +export type HostRequestLoginResponse = "Success" | "AlreadyConnected" | "Rejected"; +export const HostRequestLoginResponse: Codec; +/** Batched resource pre-allocation request (RFC 0010). */ +export interface HostRequestResourceAllocationRequest { + /** Resources to allocate. */ + resources: Array; +} +export const HostRequestResourceAllocationRequest: Codec; +/** Per-resource outcomes for a batched allocation request (RFC 0010). */ +export interface HostRequestResourceAllocationResponse { + /** Per-resource allocation outcomes, in the same order as the request. */ + outcomes: Array; +} +export const HostRequestResourceAllocationResponse: Codec; +/** Signing operation error. */ +export type HostSignPayloadError = +/** Payload could not be deserialized. */ +{ + tag: "FailedToDecode"; + value?: undefined; +} +/** User rejected signing. */ + | { + tag: "Rejected"; + value?: undefined; +} +/** Not authenticated. */ + | { + tag: "PermissionDenied"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const HostSignPayloadError: Codec; +/** Request to sign an extrinsic payload with a product account. */ +export interface HostSignPayloadRequest { + /** Product account that will sign this payload. */ + account: ProductAccountId; + /** The extrinsic payload to sign. */ + payload: HostSignPayloadData; +} +export const HostSignPayloadRequest: Codec; +/** Result of a signing operation. */ +export interface HostSignPayloadResponse { + /** The cryptographic signature. */ + signature: HexString; + /** Full signed transaction, if requested. */ + signedTransaction?: HexString; +} +export const HostSignPayloadResponse: Codec; +/** + * Sign a Substrate extrinsic payload with a non-product (legacy) account. + * Contains the same fields as [`HostSignPayloadRequest`] minus `address` + * (replaced by `signer`). + */ +export interface HostSignPayloadWithLegacyAccountRequest { + /** Signer address (SS58 or hex) of the legacy account. */ + signer: string; + /** The extrinsic payload to sign. */ + payload: HostSignPayloadData; +} +export const HostSignPayloadWithLegacyAccountRequest: Codec; +/** A raw signing request pairing an account with the payload to sign. */ +export interface HostSignRawRequest { + /** Product account that will sign this payload. */ + account: ProductAccountId; + /** The payload to sign. */ + payload: RawPayload; +} +export const HostSignRawRequest: Codec; +/** + * Sign raw bytes with a non-product (legacy) account. The signer field + * identifies which legacy account to use. + */ +export interface HostSignRawWithLegacyAccountRequest { + /** Signer address (SS58 or hex) of the legacy account. */ + signer: string; + /** The data to sign. */ + payload: RawPayload; +} +export const HostSignRawWithLegacyAccountRequest: Codec; +/** Current theme state pushed to subscribers. */ +export interface HostThemeSubscribeItem { + /** Theme name. */ + name: ThemeName; + /** Light or dark variant. */ + variant: ThemeVariant; +} +export const HostThemeSubscribeItem: Codec; +/** Render work sent by the host when a native custom-message cell appears. */ +export interface ProductChatCustomMessageRenderRequest { + /** Stable identifier used to correlate triggered actions. */ + messageId: string; + /** Product-defined discriminator used to select a renderer. */ + messageType: string; + /** Stored product-defined message payload. */ + payload: HexString; +} +export const ProductChatCustomMessageRenderRequest: Codec; +/** Request to fetch the body of a pinned block. */ +export interface RemoteChainHeadBodyRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Follow subscription identifier. */ + followSubscriptionId: string; + /** Block hash. */ + hash: HexString; +} +export const RemoteChainHeadBodyRequest: Codec; +/** Response to a body request; results arrive as follow events. */ +export interface RemoteChainHeadBodyResponse { + /** Started operation result. */ + operation: OperationStartedResult; +} +export const RemoteChainHeadBodyResponse: Codec; +/** Request to invoke a runtime call at a pinned block. */ +export interface RemoteChainHeadCallRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Follow subscription identifier. */ + followSubscriptionId: string; + /** Block hash. */ + hash: HexString; + /** Runtime API function name. */ + function: string; + /** SCALE-encoded call parameters. */ + callParameters: HexString; +} +export const RemoteChainHeadCallRequest: Codec; +/** Response to a runtime call request; the output arrives as a follow event. */ +export interface RemoteChainHeadCallResponse { + /** Started operation result. */ + operation: OperationStartedResult; +} +export const RemoteChainHeadCallResponse: Codec; +/** Request to continue a paused chain-head operation. */ +export interface RemoteChainHeadContinueRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Follow subscription identifier. */ + followSubscriptionId: string; + /** Operation identifier. */ + operationId: string; +} +export const RemoteChainHeadContinueRequest: Codec; +/** Event emitted on a chain-head follow subscription. */ +export type RemoteChainHeadFollowItem = +/** First event of the subscription, describing the current finalized blocks. */ +{ + tag: "Initialized"; + value: { + finalizedBlockHashes: Array; + finalizedBlockRuntime?: RuntimeType; + }; +} +/** A new non-finalized block was announced. */ + | { + tag: "NewBlock"; + value: { + blockHash: HexString; + parentBlockHash: HexString; + newRuntime?: RuntimeType; + }; +} +/** The best block has changed. */ + | { + tag: "BestBlockChanged"; + value: { + bestBlockHash: HexString; + }; +} +/** One or more blocks were finalized. */ + | { + tag: "Finalized"; + value: { + finalizedBlockHashes: Array; + prunedBlockHashes: Array; + }; +} +/** A body operation completed. */ + | { + tag: "OperationBodyDone"; + value: { + operationId: string; + value: Array; + }; +} +/** A runtime call operation completed. */ + | { + tag: "OperationCallDone"; + value: { + operationId: string; + output: HexString; + }; +} +/** A storage operation produced a batch of results. */ + | { + tag: "OperationStorageItems"; + value: { + operationId: string; + items: Array; + }; +} +/** A storage operation finished emitting results. */ + | { + tag: "OperationStorageDone"; + value: { + operationId: string; + }; +} +/** A storage operation is paused until the product requests continuation. */ + | { + tag: "OperationWaitingForContinue"; + value: { + operationId: string; + }; +} +/** The operation failed because the required data was not accessible; it can be retried. */ + | { + tag: "OperationInaccessible"; + value: { + operationId: string; + }; +} +/** The operation failed with an error. */ + | { + tag: "OperationError"; + value: { + operationId: string; + error: string; + }; +} +/** The subscription was stopped by the host and is no longer valid. */ + | { + tag: "Stop"; + value?: undefined; +}; +export const RemoteChainHeadFollowItem: Codec; +/** Request to start a chain-head follow subscription. */ +export interface RemoteChainHeadFollowRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Whether to include runtime information in events. */ + withRuntime: boolean; +} +export const RemoteChainHeadFollowRequest: Codec; +/** Request to fetch the header of a pinned block. */ +export interface RemoteChainHeadHeaderRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Follow subscription identifier. */ + followSubscriptionId: string; + /** Block hash. */ + hash: HexString; +} +export const RemoteChainHeadHeaderRequest: Codec; +/** Response containing the requested block header. */ +export interface RemoteChainHeadHeaderResponse { + /** SCALE-encoded block header. */ + header?: HexString; +} +export const RemoteChainHeadHeaderResponse: Codec; +/** Request to stop an in-progress chain-head operation. */ +export interface RemoteChainHeadStopOperationRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Follow subscription identifier. */ + followSubscriptionId: string; + /** Operation identifier. */ + operationId: string; +} +export const RemoteChainHeadStopOperationRequest: Codec; +/** Request to query storage at a pinned block. */ +export interface RemoteChainHeadStorageRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Follow subscription identifier. */ + followSubscriptionId: string; + /** Block hash. */ + hash: HexString; + /** Storage items to query. */ + items: Array; + /** Optional child trie. */ + childTrie?: HexString; +} +export const RemoteChainHeadStorageRequest: Codec; +/** Response to a storage request; results arrive as follow events. */ +export interface RemoteChainHeadStorageResponse { + /** Started operation result. */ + operation: OperationStartedResult; +} +export const RemoteChainHeadStorageResponse: Codec; +/** Request to release pinned blocks. */ +export interface RemoteChainHeadUnpinRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Follow subscription identifier. */ + followSubscriptionId: string; + /** Block hashes to unpin. */ + hashes: Array; +} +export const RemoteChainHeadUnpinRequest: Codec; +/** Error from [`crate::api::Chain::get_chain_info`]. */ +export type RemoteChainInfoError = +/** The host does not serve the requested chain. */ +{ + tag: "NotSupported"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: GenericError; +}; +export const RemoteChainInfoError: Codec; +/** Request to resolve one chain identifier against the host's environment. */ +export interface RemoteChainInfoRequest { + /** Chain to resolve. */ + chain: ChainIdentifier; +} +export const RemoteChainInfoRequest: Codec; +/** Response carrying the resolved chain data. */ +export interface RemoteChainInfoResponse { + /** Ecosystem the host is configured for, e.g. "polkadot", "kusama", "paseo". */ + network: string; + /** Chain this response resolves, echoed from the request. */ + chain: ChainIdentifier; + /** Genesis hash identifying the chain in all chain-scoped calls. */ + genesisHash: HexString; +} +export const RemoteChainInfoResponse: Codec; +/** Request for the display name of a chain. */ +export interface RemoteChainSpecChainNameRequest { + /** Chain genesis hash. */ + genesisHash: HexString; +} +export const RemoteChainSpecChainNameRequest: Codec; +/** Response containing the chain display name. */ +export interface RemoteChainSpecChainNameResponse { + /** Chain display name. */ + chainName: string; +} +export const RemoteChainSpecChainNameResponse: Codec; +/** Request for the canonical genesis hash of a chain. */ +export interface RemoteChainSpecGenesisHashRequest { + /** Chain genesis hash requested by the product. */ + genesisHash: HexString; +} +export const RemoteChainSpecGenesisHashRequest: Codec; +/** Response containing the canonical genesis hash. */ +export interface RemoteChainSpecGenesisHashResponse { + /** Chain genesis hash. */ + genesisHash: HexString; +} +export const RemoteChainSpecGenesisHashResponse: Codec; +/** Request for the JSON-encoded properties of a chain. */ +export interface RemoteChainSpecPropertiesRequest { + /** Chain genesis hash. */ + genesisHash: HexString; +} +export const RemoteChainSpecPropertiesRequest: Codec; +/** Response containing the chain properties. */ +export interface RemoteChainSpecPropertiesResponse { + /** JSON-encoded properties. */ + properties: string; +} +export const RemoteChainSpecPropertiesResponse: Codec; +/** Request to broadcast a signed transaction. */ +export interface RemoteChainTransactionBroadcastRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Signed transaction bytes. */ + transaction: HexString; +} +export const RemoteChainTransactionBroadcastRequest: Codec; +/** Response to a transaction broadcast request. */ +export interface RemoteChainTransactionBroadcastResponse { + /** Broadcast operation identifier, if available. */ + operationId?: string; +} +export const RemoteChainTransactionBroadcastResponse: Codec; +/** Request to stop broadcasting a transaction. */ +export interface RemoteChainTransactionStopRequest { + /** Chain genesis hash. */ + genesisHash: HexString; + /** Operation identifier of the broadcast to stop. */ + operationId: string; +} +export const RemoteChainTransactionStopRequest: Codec; +/** remote-permission request (RFC 0002). */ +export interface RemotePermissionRequest { + /** Permission requested by the product. */ + permission: RemotePermission; +} +export const RemotePermissionRequest: Codec; +/** Outcome of a remote-permission request. */ +export interface RemotePermissionResponse { + /** Whether the permission was granted. */ + granted: boolean; +} +export const RemotePermissionResponse: Codec; +/** Item containing an optional preimage lookup result. */ +export interface RemotePreimageLookupSubscribeItem { + /** Preimage data, if found. */ + value?: HexString; +} +export const RemotePreimageLookupSubscribeItem: Codec; +/** Request to subscribe to preimage lookup results. */ +export interface RemotePreimageLookupSubscribeRequest { + /** Hash of the preimage. */ + key: HexString; +} +export const RemotePreimageLookupSubscribeRequest: Codec; +/** Statement proof creation error. */ +export type RemoteStatementStoreCreateProofError = +/** Signing operation failed. */ +{ + tag: "UnableToSign"; + value?: undefined; +} +/** Account not recognized. */ + | { + tag: "UnknownAccount"; + value?: undefined; +} +/** Catch-all. */ + | { + tag: "Unknown"; + value: { + reason: string; + }; +}; +export const RemoteStatementStoreCreateProofError: Codec; +/** Request to create a cryptographic proof for a statement. */ +export interface RemoteStatementStoreCreateProofRequest { + /** Product account that should create the proof. */ + productAccountId: ProductAccountId; + /** Statement to prove. */ + statement: Statement; +} +export const RemoteStatementStoreCreateProofRequest: Codec; +/** Response containing a statement proof. */ +export interface RemoteStatementStoreCreateProofResponse { + /** Created statement proof. */ + proof: StatementProof; +} +export const RemoteStatementStoreCreateProofResponse: Codec; +/** + * Page of signed statements delivered by the statement store subscription + * (RFC 0008). The `is_complete` flag distinguishes the historical-dump phase + * (`false`) from the live-update phase (`true`). + */ +export interface RemoteStatementStoreSubscribeItem { + /** Signed statements matching the subscription. */ + statements: Array; + /** + * `false` while the host is still streaming the historical dump (more + * pages to follow). `true` once the dump is complete; all subsequent + * pages are also `true` and carry only newly-arrived statements. + */ + isComplete: boolean; +} +export const RemoteStatementStoreSubscribeItem: Codec; +/** Request to subscribe to statements via a topic filter (RFC 0008). */ +export type RemoteStatementStoreSubscribeRequest = +/** AND: statement must contain every listed topic. */ +{ + tag: "MatchAll"; + value: Array; +} +/** OR: statement must contain at least one listed topic. */ + | { + tag: "MatchAny"; + value: Array; +}; +export const RemoteStatementStoreSubscribeRequest: Codec; +/** Vertical alignment options. */ +export type VerticalAlignment = "Top" | "Center" | "Bottom"; +export const VerticalAlignment: Codec; +/** An sr25519 (schnorrkel) VRF signature: the VRF pre-output and its proof. */ +export interface VrfSignature { + /** schnorrkel `VRFPreOut` — the 32-byte VRF output point. */ + preOutput: HexString; + /** schnorrkel `VRFProof` — the 64-byte DLEQ proof. */ + proof: HexString; +} +export const VrfSignature: Codec; +/** One `append_message` call replayed against the signing transcript. */ +export interface VrfTranscriptItem { + /** Merlin `append_message` label. */ + label: HexString; + /** Merlin `append_message` value. */ + value: HexString; +} +export const VrfTranscriptItem: Codec; + +} + + +/** + * Handle returned by TrUAPI subscription APIs. + **/ +export interface Subscription { + /** + * Stop the subscription. Calling this more than once has no additional effect. + **/ + unsubscribe: () => void; + /** + * Transport-assigned request id for the subscription start frame. + * + * Methods that accept a `followSubscriptionId` use this value to scope + * follow-up requests to a specific active subscription. + **/ + subscriptionId: string; +} +/** + * Terminal error delivered through `Observer.error` for every non-normal + * subscription end. When the peer interrupted the stream with a typed payload, + * `reason` carries the decoded `Reason`; otherwise `reason` is `undefined` and + * the underlying transport/decode error is preserved on `cause`. + * + * Discriminate with `error.reason !== undefined` (or `'reason' in error`). + **/ +export declare class SubscriptionError extends Error { + /** + * Typed payload supplied by the peer when it interrupted the subscription. + * `undefined` when the stream ended for any other reason (transport close, + * decode failure, malformed interrupt payload). + **/ + readonly reason?: Reason; + constructor(message: string, options?: { + reason?: Reason; + cause?: unknown; + }); +} +/** + * Minimal Observable-compatible observer shape used by generated subscription + * APIs without depending on RxJS. + * + * `Reason` is the typed interrupt payload for the originating subscription. + * Methods without a typed interrupt resolve `Reason` to `never`, leaving + * `error.reason` typed as `undefined`. + **/ +export interface Observer { + /** + * Called with each successfully decoded subscription item. + **/ + next(value: Item): void; + /** + * Called once when the stream terminates with an error. Inspect + * `error.reason` to distinguish a typed peer interrupt from a transport or + * decode failure (`error.cause` carries the underlying failure in the + * latter case). + **/ + error(error: SubscriptionError): void; + /** + * Called once when the peer normally completes the stream. + **/ + complete(): void; +} +declare global { + interface SymbolConstructor { + readonly observable: unique symbol; + } +} +/** + * Minimal Observable-compatible object returned by generated subscription APIs. + * + * Implements the ES Observable interop protocol so that consumers can pass + * an instance straight to `rxjs.from(...)`. + **/ +export interface ObservableLike { + /** + * Start the stream and receive `next`, `error`, and `complete` callbacks. + **/ + subscribe(observer?: Partial>): Subscription; + /** + * Observable interop hook. Returns `this`. + **/ + [Symbol.observable](): ObservableLike; +} +/** + * Observable source accepted by generated channel methods as the + * product-to-host request stream. Structurally satisfied by RxJS subjects and + * observables as well as generated `ObservableLike` values. + **/ +export interface ObservableSource { + /** + * Start consuming the source until the returned handle unsubscribes. + **/ + subscribe(observer: Partial>): { + unsubscribe(): void; + }; +} +/** + * Numeric frame ids for a one-shot request method. + **/ +export interface RequestFrameIds { + /** + * Wire discriminant for the outbound request frame. + **/ + request: number; + /** + * Wire discriminant for the inbound response frame. + **/ + response: number; +} +/** + * Numeric frame ids for a subscription method. + **/ +export interface SubscriptionFrameIds { + /** + * Wire discriminant for the outbound start frame. + **/ + start: number; + /** + * Wire discriminant for the outbound stop frame. + **/ + stop: number; + /** + * Wire discriminant for the inbound interrupt frame. + **/ + interrupt: number; + /** + * Wire discriminant for the inbound receive frame. + **/ + receive: number; +} +/** + * Options accepted by `TrUApiTransport.request`. + **/ +export interface RequestParams { + /** + * Wire discriminants for this request method. + **/ + ids: RequestFrameIds; + /** + * SCALE-encoded request payload bytes. + **/ + payload: Uint8Array; + /** + * Decode SCALE response payload bytes into the wire `ResultPayload` + * envelope. The transport unwraps the envelope into `ResultAsync`. + **/ + decodeResponse: (payload: Uint8Array) => ResultPayload; +} +/** + * Options accepted by `TrUApiTransport.subscribeRaw`. + **/ +export interface SubscribeRawParams { + /** + * Wire discriminants for this subscription method. + **/ + ids: SubscriptionFrameIds; + /** + * SCALE-encoded subscription start payload bytes. + **/ + payload: Uint8Array; + /** + * Called with raw SCALE receive payload bytes. + **/ + onReceive: (payload: Uint8Array) => void; + /** + * Called with raw SCALE interrupt payload bytes when the peer interrupts the subscription. + **/ + onInterrupt?: (payload: Uint8Array) => void; + /** + * Called when the underlying provider closes while the subscription is active. + **/ + onClose?: (error: Error) => void; +} +/** + * Handler for a subscription initiated by the native host. + **/ +export type HostInitiatedSubscriptionHandler = (request: Request) => ObservableSource; +/** Product-side registration for one host-initiated subscription method. **/ +export interface HostInitiatedSubscriptionRegistration { + /** Install or replace the handler used for future start frames. **/ + setHandler(handler: HostInitiatedSubscriptionHandler): { + unsubscribe(): void; + }; +} +/** Options used to register a host-initiated subscription method. **/ +export interface RegisterHostInitiatedSubscriptionParams { + /** Wire discriminants for the host-initiated subscription. **/ + ids: SubscriptionFrameIds; + /** Decode the host's start payload. **/ + decodeRequest(payload: Uint8Array): Request; + /** Encode one product renderer emission. **/ + encodeItem(item: Item): Uint8Array; + /** Exact payload used when the product declines a render instance. **/ + interruptPayload: Uint8Array; + /** Number of starts retained before a handler is installed. **/ + bufferCapacity: number; +} +/** + * Byte-level transport used by generated client stubs. + **/ +export interface TrUApiTransport { + /** + * SCALE codec version used by generated handshake calls. + * + * @deprecated TODO(shared-core-wire): remove this public transport field once + * generated handshake requests read `TRUAPI_CODEC_VERSION` directly instead + * of going through transport state. + **/ + readonly codecVersion: number; + /** + * Send a one-shot request and resolve with the typed Ok/Err outcome. + **/ + request(params: RequestParams): ResultAsync; + /** + * Start a subscription and return a handle that can stop it. + **/ + subscribeRaw(params: SubscribeRawParams): Subscription; + /** Register product-side handling for a host-initiated subscription. **/ + registerHostInitiatedSubscription(params: RegisterHostInitiatedSubscriptionParams): HostInitiatedSubscriptionRegistration; + /** + * Tear down the transport and release the listeners it registered on the + * underlying `WireProvider`. Pending requests reject and live subscriptions + * receive `onClose`. Idempotent. + * + * The provider itself is left alone; the caller decides whether to also + * call `provider.dispose()` (long-lived hosts that swap providers will + * typically dispose the transport but keep the provider). + **/ + dispose(): void; +} +/** + * Tagged payload inside a TrUAPI wire frame. + **/ +export interface Payload { + /** + * Wire-table numeric discriminant. + **/ + id: number; + /** + * SCALE-encoded payload body. + **/ + value: Uint8Array; +} +/** + * Top-level TrUAPI wire message. + **/ +export interface ProtocolMessage { + /** + * Request id used to correlate request/response and subscription frames. + **/ + requestId: string; + /** + * Tagged SCALE payload carried by this frame. + **/ + payload: Payload; +} +/** + * Raw SCALE-wire-frame pipe abstraction used by the transport. A `WireProvider` + * is the low-level channel (a `MessagePort` or iframe `postMessage` link) that + * carries encoded frames between the product and the host. + **/ +export interface WireProvider { + /** + * Send a complete SCALE-encoded wire frame to the peer. + **/ + postMessage(message: Uint8Array): void; + /** + * Register a callback for inbound SCALE-encoded wire frames. + **/ + subscribe(callback: (message: Uint8Array) => void): () => void; + /** + * Register a callback for provider-level close or failure events. + * + * Providers keep a terminal close reason. The callback fires at most once + * for an active subscription, and fires immediately when registered after + * the provider has already closed. + **/ + subscribeClose?(callback: (error: Error) => void): () => void; + /** + * Release provider resources and close the underlying pipe. + **/ + dispose(): void; +} +/** + * A {@link WireProvider} backed by a WebSocket, which reports when its socket + * is up. Awaiting {@link WebSocketWireProvider.opened} is optional: frames + * posted earlier are queued and flushed on open. + **/ +export interface WebSocketWireProvider extends WireProvider { + /** Resolves once the socket is open, rejects if it never connects. */ + opened: Promise; +} +/** + * Encode a `ProtocolMessage` into a SCALE wire frame. + **/ +export declare function encodeWireMessage(message: ProtocolMessage): Result; +/** + * Decode a SCALE wire frame into a `ProtocolMessage`. + **/ +export declare function decodeWireMessage(message: Uint8Array): Result; +/** + * Create a provider for the child side of an iframe `postMessage` channel. + * + * `target` is the `Window` the provider posts to (typically `window.parent`); + * `hostOrigin` is the pinned `targetOrigin` for outbound frames and the + * required `event.origin` of inbound frames. The provider only delivers + * frames whose `event.source === target` and `event.origin === hostOrigin`, + * so it cannot be coerced by an unrelated frame parent. + **/ +export declare function createIframeProvider(options: { + target: Window; + hostOrigin: string; +}): WireProvider; +/** + * Create a provider from a web or Electron `MessagePort`. + **/ +export declare function createMessagePortProvider(port: MessagePort | Promise): WireProvider; +/** + * Wire provider over a binary WebSocket, one message per SCALE frame. + * + * This is the transport a host exposes on a loopback socket: the Rust core's + * `ws-bridge`, and `truapi-host signing-host --frame-listen`. The frame bytes + * are identical to what the {@link createMessagePortProvider} path carries, so + * this is a pipe and nothing more. + * + * Frames posted before the socket opens are queued and flushed on open, so a + * caller never has to await {@link WebSocketWireProvider.opened} first. + **/ +export declare function createWebSocketProvider(url: string): WebSocketWireProvider; + + +export declare const TRUAPI_VERSION: 1; +export declare const TRUAPI_CODEC_VERSION: 1; +/** Account lookup, aliasing, and proof generation. */ +export declare class AccountClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Subscribe to account connection status changes. */ + connectionStatusSubscribe(): ObservableLike; + /** Retrieve a product-scoped account. */ + getAccount(request: T.HostAccountGetRequest): ResultAsync>; + /** Retrieve the contextual alias for a context and ring. */ + getAccountAlias(request: T.HostAccountGetAliasRequest): ResultAsync>; + /** Generate a ring VRF proof with an explicitly registered member key. */ + createAccountProof(request: T.HostAccountCreateProofRequest): ResultAsync>; + /** + * Produce an sr25519 (schnorrkel) VRF signature from a product account. + * + * The host builds a Merlin transcript from `transcriptLabel` and `items` + * and signs it with the account's key, returning the VRF pre-output and + * proof. Authorized like signing: local when `AutoSigning` covers the + * account, otherwise a per-call user confirmation. + */ + signVrf(request: T.HostAccountSignVrfRequest): ResultAsync>; + /** Register a ring-VRF key owned by the calling product. */ + registerRingVrfKey(request: T.HostAccountRegisterRingVrfKeyRequest): ResultAsync>; + /** List registered ring-VRF keys owned by a product. */ + listRingVrfKeys(request: T.HostAccountListRingVrfKeysRequest): ResultAsync, CallErrorValue>; + /** Sign bytes directly with a registered ring-VRF member key. */ + ringVrfSign(request: T.HostAccountRingVrfSignRequest): ResultAsync>; + /** + * List non-product accounts the user owns. + * + * Current hosts do not expose non-product accounts, so the list is empty. + */ + getLegacyAccounts(): ResultAsync>; + /** Fetch the user's primary identity. */ + getUserId(): ResultAsync>; + /** + * Request the host to present the login flow to the user. + * + * Products should call this in response to a user action (e.g. tapping a + * "Sign in" button), not automatically on load. + */ + requestLogin(request: T.HostRequestLoginRequest): ResultAsync>; +} +/** Chain interaction methods. */ +export declare class ChainClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Follow the chain head and receive block events. */ + followHeadSubscribe({ request }: { + request: T.RemoteChainHeadFollowRequest; + }): ObservableLike; + /** Fetch a block header. */ + getHeadHeader(request: T.RemoteChainHeadHeaderRequest): ResultAsync>; + /** Fetch a block body. */ + getHeadBody(request: T.RemoteChainHeadBodyRequest): ResultAsync>; + /** Query runtime storage at a specific block. */ + getHeadStorage(request: T.RemoteChainHeadStorageRequest): ResultAsync>; + /** Invoke a runtime call at a specific block. */ + callHead(request: T.RemoteChainHeadCallRequest): ResultAsync>; + /** Release pinned blocks. */ + unpinHead(request: T.RemoteChainHeadUnpinRequest): ResultAsync>; + /** Continue a paused chain-head operation. */ + continueHead(request: T.RemoteChainHeadContinueRequest): ResultAsync>; + /** Stop a chain-head operation. */ + stopHeadOperation(request: T.RemoteChainHeadStopOperationRequest): ResultAsync>; + /** Fetch the canonical genesis hash for a chain. */ + getSpecGenesisHash(request: T.RemoteChainSpecGenesisHashRequest): ResultAsync>; + /** Fetch the display name of a chain. */ + getSpecChainName(request: T.RemoteChainSpecChainNameRequest): ResultAsync>; + /** Fetch the JSON-encoded properties of a chain. */ + getSpecProperties(request: T.RemoteChainSpecPropertiesRequest): ResultAsync>; + /** Broadcast a signed transaction. */ + broadcastTransaction(request: T.RemoteChainTransactionBroadcastRequest): ResultAsync>; + /** Stop a transaction broadcast. */ + stopTransaction(request: T.RemoteChainTransactionStopRequest): ResultAsync>; + /** + * Resolve a chain identifier to its genesis hash against the host's + * configured environment (RFC 0026). + */ + getChainInfo(request: T.RemoteChainInfoRequest): ResultAsync>; +} +/** Chat room, bot, and message APIs. */ +export declare class ChatClient { + private readonly transport; + private readonly customMessageRenderRegistration; + constructor(transport: TrUApiTransport); + /** Create a chat room. */ + createRoom(request: T.HostChatCreateRoomRequest): ResultAsync>; + /** Register a chat bot. */ + registerBot(request: T.HostChatRegisterBotRequest): ResultAsync>; + /** Subscribe to the list of chat rooms. */ + listSubscribe(): ObservableLike; + /** + * Post a message to a chat room. + * + * The host bounds and screens what it forwards. Message text is capped at + * 16 KiB and keeps line breaks and tabs, but is rejected for other + * control characters and for bidirectional overrides. Identifiers and + * display names are normalized and screened. A message carries at most 32 + * actions and 32 media items, a custom payload at most 256 KiB, and a URL + * at most 2 KiB which must be `https` or an inline raster image. A + * rejection reports `MessageTooLarge` when the body or custom payload is + * over budget, and `Unknown` with a reason naming the field otherwise. + * + * The returned `messageId` is the correlation key for any action the + * message carries: a later `actionSubscribe` trigger names it. + */ + postMessage(request: T.HostChatPostMessageRequest): ResultAsync>; + /** Subscribe to received chat actions. */ + actionSubscribe(): ObservableLike; + /** Streams renderer trees for one stored custom message. */ + onCustomMessageRender(handler: (request: T.ProductChatCustomMessageRenderRequest) => ObservableSource): { + unsubscribe(): void; + }; +} +/** + * CoinPayment operations. + * + * RFC 0017 describes `Resolvable` values for long-running operations. + * TrUAPI represents those as subscriptions whose items are the RFC status + * updates. + */ +export declare class CoinPaymentClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Create a new firewalled CoinPayment purse. */ + createPurse(request: T.HostCoinPaymentCreatePurseRequest): ResultAsync>; + /** Query product-visible purse metadata and balance. */ + queryPurse(request: T.HostCoinPaymentQueryPurseRequest): ResultAsync>; + /** Transfer balance between local purses. */ + rebalancePurse({ request }: { + request: T.HostCoinPaymentRebalancePurseRequest; + }): ObservableLike>; + /** Delete a purse after draining its balance into another local purse. */ + deletePurse({ request }: { + request: T.HostCoinPaymentDeletePurseRequest; + }): ObservableLike>; + /** Create a receivable public key for depositing into a purse. */ + createReceivable(request: T.HostCoinPaymentCreateReceivableRequest): ResultAsync>; + /** Create a cheque paying from a local purse to a receivable. */ + createCheque(request: T.HostCoinPaymentCreateChequeRequest): ResultAsync>; + /** Claim coins from a cheque into the receivable's purse. */ + deposit({ request }: { + request: T.HostCoinPaymentDepositRequest; + }): ObservableLike>; + /** Attempt to return coins associated with a receivable. */ + refund({ request }: { + request: T.HostCoinPaymentRefundRequest; + }): ObservableLike>; + /** Listen for a cheque delivered through a standard transmission channel. */ + listenForPayment({ request }: { + request: T.HostCoinPaymentListenForRequest; + }): ObservableLike>; +} +/** Deterministic entropy derivation. */ +export declare class EntropyClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Derive deterministic entropy. */ + derive(request: T.HostDeriveEntropyRequest): ResultAsync>; +} +/** Local key/value storage scoped to the calling product. */ +export declare class LocalStorageClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Read a value by key. */ + read(request: T.HostLocalStorageReadRequest): ResultAsync>; + /** Write a value to a key. */ + write(request: T.HostLocalStorageWriteRequest): ResultAsync>; + /** Clear a value by key. */ + clear(request: T.HostLocalStorageClearRequest): ResultAsync>; +} +/** Notification methods for locally-rendered push notifications. */ +export declare class NotificationsClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** + * Send a push notification to the user. + * + * Returns a [`NotificationId`](crate::v01::NotificationId) that can be + * passed to [`cancel_push_notification`](Self::cancel_push_notification) + * to retract a scheduled notification. When `scheduled_at` is set the host + * persists the notification across restarts and fires it through the + * platform-native scheduler. See [RFC 0019]. + * + * [RFC 0019]: https://github.com/paritytech/host-rust-core/blob/main/docs/rfcs/0019-scheduled-notifications.md + */ + sendPushNotification(request: T.HostPushNotificationRequest): ResultAsync>; + /** + * Cancels a previously issued push notification. + * + * Cancellation is idempotent: returns `Ok(())` whether the notification is + * still pending, already fired, or was never issued. See [RFC 0019]. + * + * [RFC 0019]: https://github.com/paritytech/host-rust-core/blob/main/docs/rfcs/0019-scheduled-notifications.md + */ + cancelPushNotification(request: T.HostPushNotificationCancelRequest): ResultAsync>; +} +/** Payment request and balance/status subscription methods. */ +export declare class PaymentClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Subscribe to payment balance updates. */ + balanceSubscribe({ request }: { + request: T.HostPaymentBalanceSubscribeRequest; + }): ObservableLike>; + /** Request a payment from the user. */ + request(request: T.HostPaymentRequest): ResultAsync>; + /** Subscribe to payment lifecycle updates for a specific payment. */ + statusSubscribe({ request }: { + request: T.HostPaymentStatusSubscribeRequest; + }): ObservableLike>; + /** Top up the user's payment balance. */ + topUp(request: T.HostPaymentTopUpRequest): ResultAsync>; +} +/** Permission request methods. */ +export declare class PermissionsClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Request a device-capability permission from the user. */ + requestDevicePermission(request: T.HostDevicePermissionRequest): ResultAsync>; + /** Request a remote-operation permission. */ + requestRemotePermission(request: T.RemotePermissionRequest): ResultAsync>; +} +/** Preimage lookup and submission methods. */ +export declare class PreimageClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Subscribe to preimage lookups for a given key. */ + lookupSubscribe({ request }: { + request: T.RemotePreimageLookupSubscribeRequest; + }): ObservableLike; + /** Submit a preimage. Returns the preimage key (hash) on success. */ + submit(request: HexString): ResultAsync>; +} +/** Resource pre-allocation (allowance management). */ +export declare class ResourceAllocationClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Request the host to pre-allocate one or more resources. */ + request(request: T.HostRequestResourceAllocationRequest): ResultAsync>; +} +/** Signing operations. */ +export declare class SigningClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** + * Construct a transaction for a product account. + * + * Under Extrinsic V5, omitting `VerifyMultiSignature` from `extensions` + * lets the host sign with the signer's key. Listing it — as `Disabled`, + * with a proof in a later extension — encodes the given bytes verbatim and + * returns an unsigned transaction. + */ + createTransaction(request: T.ProductAccountTxPayload): ResultAsync>; + /** + * Construct a transaction for a non-product (legacy) account. + * + * The V5 `VerifyMultiSignature` rule is the same as + * [`Signing::create_transaction`]: omit it and the host signs, list it and + * the given bytes are used with no host signature. + */ + createTransactionWithLegacyAccount(request: T.LegacyAccountTxPayload): ResultAsync>; + /** Sign raw bytes with a non-product account. */ + signRawWithLegacyAccount(request: T.HostSignRawWithLegacyAccountRequest): ResultAsync>; + /** Sign an extrinsic payload with a non-product account. */ + signPayloadWithLegacyAccount(request: T.HostSignPayloadWithLegacyAccountRequest): ResultAsync>; + /** Sign raw bytes or a message. */ + signRaw(request: T.HostSignRawRequest): ResultAsync>; + /** Sign an extrinsic payload. */ + signPayload(request: T.HostSignPayloadRequest): ResultAsync>; +} +/** Statement store methods. */ +export declare class StatementStoreClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Subscribe to statements matching a topic filter. */ + subscribe({ request }: { + request: T.RemoteStatementStoreSubscribeRequest; + }): ObservableLike>; + /** + * Create a proof for a statement. + * + * **Deprecated:** use [`create_proof_authorized`](Self::create_proof_authorized) + * instead, which uses a pre-allocated allowance account and does not + * require a per-call signing prompt. Pairing hosts may reject this method + * when their signing channel cannot sign statement proof payloads exactly. + */ + createProof(request: T.RemoteStatementStoreCreateProofRequest): ResultAsync>; + /** + * Create a proof for a statement using a pre-allocated allowance account, + * bypassing the per-call signing prompt. + */ + createProofAuthorized(request: T.Statement): ResultAsync>; + /** + * Submit a signed statement to the network. The request body is the + * [`SignedStatement`](crate::v01::SignedStatement) directly (no wrapping + * struct), matching upstream `triangle-js-sdks`. + */ + submit(request: T.SignedStatement): ResultAsync>; +} +/** + * General-purpose TrUAPI methods for handshake, feature detection, + * navigation, and runtime information. + */ +export declare class SystemClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Negotiate the wire codec version with the product. */ + handshake(): ResultAsync>; + /** Query whether the host supports a specific feature. */ + featureSupported(request: T.HostFeatureSupportedRequest): ResultAsync>; + /** + * Request the host to open a URL. + * + * An `http` or `https` URL outside the ecosystem needs a + * `RemotePermission::Remote` grant for the target host, and prompts for one + * on first use. dotNS names, `localhost`, and the app-handoff schemes + * (`mailto:`, `tel:`, `polkadot:`, `dot:`) consume no grant. The grant is + * per host and shared with outbound data access to that host, so approving + * one covers the other. + */ + navigateTo(request: T.HostNavigateToRequest): ResultAsync>; + /** + * Report the host's identity and version. + * + * Returns the host's platform, name, and version so a product knows + * exactly which host — and which build of it — is running it: for + * adapting to the host, telemetry, and attributing behaviour to a + * concrete build in diagnostics and bug reports. + */ + info(): ResultAsync>; + /** Return the product context bound to the current host runtime. */ + getProductContext(): ResultAsync>; +} +/** Host theme subscription. */ +export declare class ThemeClient { + private readonly transport; + constructor(transport: TrUApiTransport); + /** Subscribe to host theme changes. */ + subscribe(): ObservableLike; +} +export interface TrUApiClient { + readonly account: AccountClient; + readonly chain: ChainClient; + readonly chat: ChatClient; + readonly coinPayment: CoinPaymentClient; + readonly entropy: EntropyClient; + readonly localStorage: LocalStorageClient; + readonly notifications: NotificationsClient; + readonly payment: PaymentClient; + readonly permissions: PermissionsClient; + readonly preimage: PreimageClient; + readonly resourceAllocation: ResourceAllocationClient; + readonly signing: SigningClient; + readonly statementStore: StatementStoreClient; + readonly system: SystemClient; + readonly theme: ThemeClient; +} +export type Client = TrUApiClient; +export type GeneratedClientTransport = Omit & Partial>; +/** Creates the generated client facade by binding each service namespace to the + * shared transport instance. */ +export declare function createClient(transport: GeneratedClientTransport): TrUApiClient; + + +/** Context injected alongside `truapi` by the headless host runner. */ +export interface HostContext { + /** Product id served by the host. */ + productId: string; + /** Product account for `derivationIndex`, which defaults to zero. */ + productAccount(index?: number): T.ProductAccountId; +} + +declare global { + var truapi: TrUApiClient; + var host: HostContext; + var assert: (condition: unknown, ...message: unknown[]) => asserts condition; +} diff --git a/rust/crates/truapi-host-cli/js/tsconfig.json b/rust/crates/truapi-host-cli/js/tsconfig.json new file mode 100644 index 000000000..dfa3a22ca --- /dev/null +++ b/rust/crates/truapi-host-cli/js/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "allowImportingTsExtensions": true, + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, + "strict": true, + "target": "ES2022", + "types": [] + }, + "files": ["runner-types.fixture.ts"] +} diff --git a/rust/crates/truapi-host-cli/src/script_runner.rs b/rust/crates/truapi-host-cli/src/script_runner.rs index d38a22bea..dbbafd2e6 100644 --- a/rust/crates/truapi-host-cli/src/script_runner.rs +++ b/rust/crates/truapi-host-cli/src/script_runner.rs @@ -39,6 +39,8 @@ impl ScriptHostRole { const SCRATCH_TEMPLATE: &str = r#"#!/usr/bin/env bun +/// + // Scripts can use packages installed next to the script or in a parent project. const result = await truapi.account.getUserId(); @@ -54,6 +56,17 @@ console.log('user id', result.value); /// without a source checkout. const PACKAGED_RUNNER: &str = "runner.js"; +/// Self-contained injected-global declarations shipped with the runner. +const PACKAGED_SCRIPT_TYPES: &str = "script-types.d.ts"; + +/// Declaration bundle matching the selected host-script runner. +fn runner_types_path(runner: &Path) -> PathBuf { + runner + .parent() + .unwrap_or_else(|| Path::new("")) + .join(PACKAGED_SCRIPT_TYPES) +} + /// Locate the host-script runner. fn runner_path() -> PathBuf { resolve_runner( @@ -98,8 +111,15 @@ fn packaged_runner(executable: &Path) -> Option { /// Create a durable, uniquely-named TypeScript scratch file seeded with the /// public TrUAPI example. pub fn create_scratch_script(directory: &Path) -> Result { + create_scratch_script_for_runner(directory, &runner_path()) +} + +fn create_scratch_script_for_runner(directory: &Path, runner: &Path) -> Result { fs::create_dir_all(directory) .with_context(|| format!("create script directory {}", directory.display()))?; + let runner_types = runner_types_path(runner); + let runner_types = fs::read(&runner_types) + .with_context(|| format!("read host-script types {}", runner_types.display()))?; let timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap_or_default() @@ -109,6 +129,7 @@ pub fn create_scratch_script(directory: &Path) -> Result { "script-{timestamp}-{}-{sequence}.ts", std::process::id() )); + let types_path = path.with_extension("d.ts"); let mut file = match OpenOptions::new().write(true).create_new(true).open(&path) { Ok(file) => file, Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => continue, @@ -117,7 +138,31 @@ pub fn create_scratch_script(directory: &Path) -> Result { .with_context(|| format!("create scratch script {}", path.display())); } }; - file.write_all(SCRATCH_TEMPLATE.as_bytes()) + let mut types_file = match OpenOptions::new() + .write(true) + .create_new(true) + .open(&types_path) + { + Ok(file) => file, + Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => { + drop(file); + let _ = fs::remove_file(&path); + continue; + } + Err(error) => { + return Err(error) + .with_context(|| format!("create script types {}", types_path.display())); + } + }; + types_file + .write_all(&runner_types) + .with_context(|| format!("write script types {}", types_path.display()))?; + let types_name = types_path + .file_name() + .and_then(|name| name.to_str()) + .context("scratch script type filename is not valid UTF-8")?; + let contents = SCRATCH_TEMPLATE.replace("__TRUAPI_TYPES__", types_name); + file.write_all(contents.as_bytes()) .with_context(|| format!("write scratch script {}", path.display()))?; return Ok(path); } @@ -352,25 +397,91 @@ mod tests { let temporary = tempfile::tempdir()?; let script = create_scratch_script(temporary.path())?; - let contents = fs::read_to_string(script)?; + let contents = fs::read_to_string(&script)?; + let script_types = script.with_extension("d.ts"); + let script_types_name = script_types.file_name().unwrap().to_string_lossy(); assert_eq!( contents, - r#"#!/usr/bin/env bun + format!( + r#"#!/usr/bin/env bun + +/// // Scripts can use packages installed next to the script or in a parent project. const result = await truapi.account.getUserId(); -if (!result.isOk()) { - throw new Error(`getUserId failed: ${JSON.stringify(result.error)}`); -} +if (!result.isOk()) {{ + throw new Error(`getUserId failed: ${{JSON.stringify(result.error)}}`); +}} console.log('user id', result.value); "# + ) + ); + assert_eq!( + fs::read(script_types)?, + fs::read(runner_types_path(&runner_path()))? + ); + Ok(()) + } + + #[test] + fn runner_types_follow_the_selected_runner() { + assert_eq!( + [ + runner_types_path(Path::new("/checkout/js/runner.ts")), + runner_types_path(Path::new("/release/runner.js")), + ], + [ + PathBuf::from("/checkout/js/script-types.d.ts"), + PathBuf::from("/release/script-types.d.ts"), + ] + ); + } + + /// A downloaded binary has no checkout or npm package to supply editor + /// declarations, so the scratch file has to retain the shipped bundle. + #[test] + fn packaged_runner_types_are_copied_beside_the_scratch_script() -> Result<()> { + let install = tempfile::tempdir()?; + let runner = install.path().join(PACKAGED_RUNNER); + fs::write(&runner, "packaged runner")?; + fs::write( + install.path().join(PACKAGED_SCRIPT_TYPES), + "declare const packaged: true;\n", + )?; + let scripts = tempfile::tempdir()?; + + let script = create_scratch_script_for_runner(scripts.path(), &runner)?; + + assert_eq!( + fs::read_to_string(script.with_extension("d.ts"))?, + "declare const packaged: true;\n" ); Ok(()) } + /// Opening an untyped scratch file recreates the original failure, so a + /// broken install must fail before launching the editor. + #[test] + fn scratch_creation_rejects_a_runner_without_types() { + let install = tempfile::tempdir().unwrap(); + let runner = install.path().join(PACKAGED_RUNNER); + fs::write(&runner, "packaged runner").unwrap(); + let scripts = tempfile::tempdir().unwrap(); + + let error = create_scratch_script_for_runner(scripts.path(), &runner).unwrap_err(); + + assert_eq!( + error.to_string(), + format!( + "read host-script types {}", + install.path().join(PACKAGED_SCRIPT_TYPES).display() + ) + ); + } + #[test] fn host_scripts_are_run_by_bun() -> Result<()> { let temporary = tempfile::tempdir()?; diff --git a/scripts/bundle-truapi-dts.mjs b/scripts/bundle-truapi-dts.mjs index 4615ea983..77f880908 100644 --- a/scripts/bundle-truapi-dts.mjs +++ b/scripts/bundle-truapi-dts.mjs @@ -7,6 +7,10 @@ const ROOT = fileURLToPath(new URL("..", import.meta.url)); const DIST = join(ROOT, "js/packages/truapi/dist"); const OUT_DIR = join(ROOT, "js/packages/truapi/src/playground/codegen"); const OUT = join(OUT_DIR, "truapi-dts.ts"); +const HOST_SCRIPT_DTS = join( + ROOT, + "rust/crates/truapi-host-cli/js/script-types.d.ts", +); // neverthrow is hoisted to the workspace root in npm workspaces; fall back to // the per-package node_modules for non-workspace setups. async function resolveNeverthrow() { @@ -52,7 +56,10 @@ const NEVERTHROW_IMPORT_RE = /^(?:import|export)[^;]*?from\s+["']neverthrow["'];?\s*\n?/gm; function stripImports(text) { - return text.replace(RELATIVE_IMPORT_RE, "").replace(NEVERTHROW_IMPORT_RE, ""); + return text + .replace(/\r\n?/g, "\n") + .replace(RELATIVE_IMPORT_RE, "") + .replace(NEVERTHROW_IMPORT_RE, ""); } // The generated client uses `T.` and `S.` because @@ -106,6 +113,21 @@ const namespaceTReExports = tExports .map((name) => `export import ${name} = T.${name};`) .join("\n"); +async function readHostFile(relPath) { + const path = typeFiles.get(relPath); + if (!path) throw new Error(`bundle: missing ${relPath}`); + return stripImports(await readFile(path, "utf8")); +} + +const STANDALONE_EXPORT_RE = /^export(?:\s+type)?\s+\{[^}]*\};?\s*\n?/gm; +const hostTransport = (await readHostFile("transport.d.ts")).replace( + STANDALONE_EXPORT_RE, + "", +); +const hostClient = (await readHostFile("generated/client.d.ts")) + .replace(STANDALONE_EXPORT_RE, "") + .replace(/\bS\.([A-Za-z_$][\w$]*)/g, "$1"); + const chunks = []; for (const [rel, path] of typeFiles) { const text = stripImports(await readFile(path, "utf8")); @@ -115,10 +137,9 @@ for (const [rel, path] of typeFiles) { // Strip the trailing `export { ... }` from neverthrow's d.ts since we're // inlining it inside `declare module "@parity/truapi"` — re-exporting names // at the bottom isn't meaningful in that context. -const neverthrow = (await readFile(NEVERTHROW_DTS, "utf8")).replace( - /^export\s+\{[^}]*\};?\s*$/gm, - "", -); +const neverthrow = (await readFile(NEVERTHROW_DTS, "utf8")) + .replace(/\r\n?/g, "\n") + .replace(/^export\s+\{[^}]*\};?\s*$/gm, ""); const bundled = [ "// neverthrow (inlined)", @@ -132,6 +153,54 @@ const bundled = [ ...chunks, ].join("\n\n"); +const hostNeverthrow = neverthrow + .replace(/A extends readonly any\[\]/g, "A extends readonly unknown[]") + .replace( + /Fn extends \(\.\.\.args: readonly any\[\]\) => any/g, + "Fn extends (...args: never[]) => unknown", + ); +const hostScriptDts = `// Auto-generated by scripts/bundle-truapi-dts.mjs. Do not edit. + +${hostNeverthrow} + +type Encoder = (value: T) => Uint8Array; +type Decoder = (value: Uint8Array | ArrayBuffer | string) => T; +type Codec = [Encoder, Decoder] & { + enc: Encoder; + dec: Decoder; +}; +type ResultPayload = + | { success: true; value: Ok } + | { success: false; value: Err }; +type HexString = \`0x\${string}\`; +type CallErrorValue = + | { tag: "Domain"; value: DomainError } + | { tag: "Denied"; value?: undefined } + | { tag: "Unsupported"; value?: undefined } + | { tag: "MalformedFrame"; value: { reason: string } } + | { tag: "HostFailure"; value: { reason: string } }; + +${namespaceT} + +${hostTransport} + +${hostClient} + +/** Context injected alongside \`truapi\` by the headless host runner. */ +export interface HostContext { + /** Product id served by the host. */ + productId: string; + /** Product account for \`derivationIndex\`, which defaults to zero. */ + productAccount(index?: number): T.ProductAccountId; +} + +declare global { + var truapi: TrUApiClient; + var host: HostContext; + var assert: (condition: unknown, ...message: unknown[]) => asserts condition; +} +`.replace(/[ \t]+$/gm, ""); + function asTemplateLiteral(s) { return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${"); } @@ -142,7 +211,8 @@ await writeFile( `// Auto-generated by scripts/bundle-truapi-dts.mjs. Do not edit.\n` + `export const truapiDts = \`${asTemplateLiteral(bundled)}\`;\n`, ); +await writeFile(HOST_SCRIPT_DTS, hostScriptDts); console.log( - `wrote ${relative(ROOT, OUT)} (${bundled.length} chars, neverthrow inlined)`, + `wrote ${relative(ROOT, OUT)} and ${relative(ROOT, HOST_SCRIPT_DTS)} (${bundled.length} chars, neverthrow inlined)`, ); diff --git a/scripts/e2e-cli-update.mjs b/scripts/e2e-cli-update.mjs index c81c32f54..aa97acb9f 100755 --- a/scripts/e2e-cli-update.mjs +++ b/scripts/e2e-cli-update.mjs @@ -109,6 +109,11 @@ async function main() { existsSync(join(root, `versions/${version}/runner.js`)), true, ); + check( + "the product-script types ship beside the runner", + existsSync(join(root, `versions/${version}/script-types.d.ts`)), + true, + ); // The checkout's runner imports @parity/truapi by relative path. Running the // packaged one from an unrelated directory proves the client is bundled in, // so a downloaded install needs no source tree: it reaches its own env check From 59daeb1d0b83a074b01321c766291b553afa87ff Mon Sep 17 00:00:00 2001 From: pg Date: Fri, 28 Aug 2026 14:21:44 +0200 Subject: [PATCH 2/5] Mark scratch scripts as modules --- rust/crates/truapi-host-cli/src/script_runner.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/crates/truapi-host-cli/src/script_runner.rs b/rust/crates/truapi-host-cli/src/script_runner.rs index dbbafd2e6..c0cb0f6e8 100644 --- a/rust/crates/truapi-host-cli/src/script_runner.rs +++ b/rust/crates/truapi-host-cli/src/script_runner.rs @@ -40,6 +40,7 @@ impl ScriptHostRole { const SCRATCH_TEMPLATE: &str = r#"#!/usr/bin/env bun /// +export {}; // Scripts can use packages installed next to the script or in a parent project. @@ -407,6 +408,7 @@ mod tests { r#"#!/usr/bin/env bun /// +export {{}}; // Scripts can use packages installed next to the script or in a parent project. From 4a64a2ef4c3661db83057bffa608e529c0b74189 Mon Sep 17 00:00:00 2001 From: pg Date: Fri, 28 Aug 2026 14:39:09 +0200 Subject: [PATCH 3/5] Migrate legacy scratch script types --- rust/crates/truapi-host-cli/README.md | 5 +- rust/crates/truapi-host-cli/SPEC.md | 7 + rust/crates/truapi-host-cli/src/main.rs | 86 ++++++++++- .../truapi-host-cli/src/script_runner.rs | 141 ++++++++++++++++++ 4 files changed, 234 insertions(+), 5 deletions(-) diff --git a/rust/crates/truapi-host-cli/README.md b/rust/crates/truapi-host-cli/README.md index af12e8766..3bb43678b 100644 --- a/rust/crates/truapi-host-cli/README.md +++ b/rust/crates/truapi-host-cli/README.md @@ -273,7 +273,10 @@ starter calls `truapi.account.getUserId()` and prints the returned user id. The generated file references an adjacent declaration bundle, so the editor provides completion and type checking for `truapi`, `host`, and `assert` without requiring `@parity/truapi` in a parent npm project. Scripts opened -from an npm project can still import packages installed by that project. +from an npm project can still import packages installed by that project. Bare +`/script` also adds the declaration and module marker when it reopens a managed +scratch file created by an older host version; explicitly selected scripts are +not rewritten when they live outside the managed scratch directory. The TUI temporarily yields the terminal to `$VISUAL`, then `$EDITOR`, or `vi` when neither is set. After the editor exits successfully, the TUI is restored and the saved script runs through the public frame endpoint. Editor diff --git a/rust/crates/truapi-host-cli/SPEC.md b/rust/crates/truapi-host-cli/SPEC.md index 36b6380e1..773abad7c 100644 --- a/rust/crates/truapi-host-cli/SPEC.md +++ b/rust/crates/truapi-host-cli/SPEC.md @@ -841,6 +841,13 @@ declaration beside the scratch file preserves its types across session promotion and removal of older installed binary versions. The script does not emit terminal styling. +When bare `/script` reopens a remembered regular file directly inside the +managed `scripts/` directory whose name matches `script-*.ts`, it refreshes the +adjacent declaration and idempotently adds a missing relative reference or +`export {}` module marker. This migrates scratch files created by older host +versions without replacing their user-edited source. Symlinks and scripts +selected explicitly outside the managed directory are not modified. + Mnemonic-backed ephemeral signing sessions remember a path only for the current process and create scratch files under the system temporary `truapi-host/scripts` directory. diff --git a/rust/crates/truapi-host-cli/src/main.rs b/rust/crates/truapi-host-cli/src/main.rs index 0a1db6f15..04ec1a8e0 100644 --- a/rust/crates/truapi-host-cli/src/main.rs +++ b/rust/crates/truapi-host-cli/src/main.rs @@ -3417,6 +3417,18 @@ fn select_script_to_edit( last_script: &mut Option, ) -> Result { if let Some(script) = last_script.as_ref().filter(|script| script.is_file()) { + let is_managed_scratch = script.parent() == Some(scratch_script_directory) + && script + .file_name() + .and_then(|name| name.to_str()) + .is_some_and(|name| { + name.starts_with("script-") && name.ends_with(".ts") && !name.ends_with(".d.ts") + }) + && std::fs::symlink_metadata(script) + .is_ok_and(|metadata| !metadata.file_type().is_symlink()); + if is_managed_scratch { + script_runner::ensure_scratch_script_types(script)?; + } return Ok(script.clone()); } let script = script_runner::create_scratch_script(scratch_script_directory)?; @@ -3940,6 +3952,62 @@ test -s "$TRUAPI_DEV_COMMAND_TEST_READY_PATH" Ok(()) } + #[test] + fn bare_script_selection_migrates_a_legacy_managed_scratch_script() -> Result<()> { + let temporary = tempfile::tempdir()?; + let scripts = temporary.path().join("scripts"); + std::fs::create_dir_all(&scripts)?; + let legacy = scripts.join("script-legacy.ts"); + std::fs::write( + &legacy, + "#!/usr/bin/env bun\n\nconst value = await truapi.system.getProductContext();\n", + )?; + let mut last_script = Some(legacy.clone()); + + let selected = select_script_to_edit(&scripts, &mut last_script)?; + + assert_eq!( + ( + selected, + std::fs::read_to_string(&legacy)?, + legacy.with_extension("d.ts").is_file(), + ), + ( + legacy, + "#!/usr/bin/env bun\n\n/// \nexport {};\n\nconst value = await truapi.system.getProductContext();\n".to_string(), + true, + ) + ); + Ok(()) + } + + #[cfg(unix)] + #[test] + fn bare_script_selection_does_not_migrate_a_managed_symlink() -> Result<()> { + use std::os::unix::fs::symlink; + + let temporary = tempfile::tempdir()?; + let scripts = temporary.path().join("scripts"); + std::fs::create_dir_all(&scripts)?; + let external = temporary.path().join("external.ts"); + std::fs::write(&external, "console.log('external');\n")?; + let linked = scripts.join("script-linked.ts"); + symlink(&external, &linked)?; + let mut last_script = Some(linked.clone()); + + let selected = select_script_to_edit(&scripts, &mut last_script)?; + + assert_eq!( + ( + selected, + std::fs::read_to_string(&external)?, + linked.with_extension("d.ts").exists(), + ), + (linked, "console.log('external');\n".to_string(), false,) + ); + Ok(()) + } + #[test] fn explicit_script_becomes_the_next_bare_script_selection() -> Result<()> { let temporary = tempfile::tempdir()?; @@ -3953,11 +4021,21 @@ test -s "$TRUAPI_DEV_COMMAND_TEST_READY_PATH" remember_script(Some(temporary.path()), &mut last_script, explicit.clone())?; let selected = select_script_to_edit(&scripts, &mut last_script)?; - assert_eq!(remembered, explicit); - assert_eq!(selected, explicit); assert_eq!( - sessions::session_last_script(temporary.path())?.as_deref(), - Some(explicit.as_path()) + ( + remembered, + selected, + sessions::session_last_script(temporary.path())?, + std::fs::read_to_string(&explicit)?, + explicit.with_extension("d.ts").exists(), + ), + ( + explicit.clone(), + explicit.clone(), + Some(explicit), + "console.log('product');".to_string(), + false, + ) ); Ok(()) } diff --git a/rust/crates/truapi-host-cli/src/script_runner.rs b/rust/crates/truapi-host-cli/src/script_runner.rs index c0cb0f6e8..5f98ca73c 100644 --- a/rust/crates/truapi-host-cli/src/script_runner.rs +++ b/rust/crates/truapi-host-cli/src/script_runner.rs @@ -115,6 +115,89 @@ pub fn create_scratch_script(directory: &Path) -> Result { create_scratch_script_for_runner(directory, &runner_path()) } +pub fn ensure_scratch_script_types(script: &Path) -> Result<()> { + ensure_scratch_script_types_for_runner(script, &runner_path()) +} + +fn ensure_scratch_script_types_for_runner(script: &Path, runner: &Path) -> Result<()> { + let runner_types = runner_types_path(runner); + let runner_types = fs::read(&runner_types) + .with_context(|| format!("read host-script types {}", runner_types.display()))?; + let types_path = script.with_extension("d.ts"); + fs::write(&types_path, runner_types) + .with_context(|| format!("write script types {}", types_path.display()))?; + let types_name = types_path + .file_name() + .and_then(|name| name.to_str()) + .context("scratch script type filename is not valid UTF-8")?; + let contents = fs::read_to_string(script) + .with_context(|| format!("read scratch script {}", script.display()))?; + let reference = format!(r#"/// "#); + let has_reference = contents.lines().any(|line| line == reference); + let has_module_marker = contents.lines().any(|line| line == "export {};"); + if has_reference && has_module_marker { + return Ok(()); + } + + let line_ending = if contents.contains("\r\n") { + "\r\n" + } else { + "\n" + }; + let updated = if has_reference { + let reference_end = contents + .find(&reference) + .map(|start| start + reference.len()) + .context("scratch script type reference disappeared while migrating")?; + let remainder = contents[reference_end..] + .strip_prefix(line_ending) + .unwrap_or(&contents[reference_end..]); + format!( + "{}{line_ending}export {{}};{line_ending}{remainder}", + &contents[..reference_end] + ) + } else { + let header = if has_module_marker { + reference + } else { + format!("{reference}{line_ending}export {{}};") + }; + if contents.starts_with("#!") { + let shebang_end = contents + .find('\n') + .map(|index| index + 1) + .unwrap_or(contents.len()); + let remainder = contents[shebang_end..] + .strip_prefix(line_ending) + .unwrap_or(&contents[shebang_end..]); + format!( + "{}{line_ending}{header}{line_ending}{line_ending}{remainder}", + &contents[..shebang_end] + ) + } else { + format!("{header}{line_ending}{line_ending}{contents}") + } + }; + let permissions = fs::metadata(script) + .with_context(|| format!("read scratch script metadata {}", script.display()))? + .permissions(); + let parent = script + .parent() + .with_context(|| format!("scratch script has no parent: {}", script.display()))?; + let mut temporary = tempfile::NamedTempFile::new_in(parent) + .with_context(|| format!("create temporary scratch script in {}", parent.display()))?; + temporary + .write_all(updated.as_bytes()) + .with_context(|| format!("write migrated scratch script {}", script.display()))?; + fs::set_permissions(temporary.path(), permissions) + .with_context(|| format!("preserve scratch script permissions {}", script.display()))?; + temporary + .persist(script) + .map_err(|error| error.error) + .with_context(|| format!("replace migrated scratch script {}", script.display()))?; + Ok(()) +} + fn create_scratch_script_for_runner(directory: &Path, runner: &Path) -> Result { fs::create_dir_all(directory) .with_context(|| format!("create script directory {}", directory.display()))?; @@ -464,6 +547,64 @@ console.log('user id', result.value); Ok(()) } + #[test] + fn legacy_scratch_scripts_gain_current_types_without_losing_source() -> Result<()> { + let install = tempfile::tempdir()?; + let runner = install.path().join(PACKAGED_RUNNER); + fs::write(&runner, "packaged runner")?; + fs::write( + install.path().join(PACKAGED_SCRIPT_TYPES), + "declare const packaged: true;\n", + )?; + let scripts = tempfile::tempdir()?; + let script = scripts.path().join("legacy.ts"); + fs::write( + &script, + "#!/usr/bin/env bun\n\nconst value = await truapi.system.getProductContext();\n", + )?; + + ensure_scratch_script_types_for_runner(&script, &runner)?; + ensure_scratch_script_types_for_runner(&script, &runner)?; + + assert_eq!( + ( + fs::read_to_string(&script)?, + fs::read_to_string(script.with_extension("d.ts"))?, + ), + ( + "#!/usr/bin/env bun\n\n/// \nexport {};\n\nconst value = await truapi.system.getProductContext();\n".to_string(), + "declare const packaged: true;\n".to_string(), + ) + ); + Ok(()) + } + + #[test] + fn referenced_scratch_scripts_gain_the_module_marker_once() -> Result<()> { + let install = tempfile::tempdir()?; + let runner = install.path().join(PACKAGED_RUNNER); + fs::write(&runner, "packaged runner")?; + fs::write( + install.path().join(PACKAGED_SCRIPT_TYPES), + "declare const packaged: true;\n", + )?; + let scripts = tempfile::tempdir()?; + let script = scripts.path().join("referenced.ts"); + fs::write( + &script, + "#!/usr/bin/env bun\n\n/// \n\nconst value = await truapi.system.getProductContext();\n", + )?; + + ensure_scratch_script_types_for_runner(&script, &runner)?; + ensure_scratch_script_types_for_runner(&script, &runner)?; + + assert_eq!( + fs::read_to_string(script)?, + "#!/usr/bin/env bun\n\n/// \nexport {};\n\nconst value = await truapi.system.getProductContext();\n" + ); + Ok(()) + } + /// Opening an untyped scratch file recreates the original failure, so a /// broken install must fail before launching the editor. #[test] From 2b20e08af24e12eefad50db107c14fef1330dbe3 Mon Sep 17 00:00:00 2001 From: pg Date: Fri, 28 Aug 2026 16:40:23 +0200 Subject: [PATCH 4/5] Drop scratch script migration --- rust/crates/truapi-host-cli/README.md | 5 +- rust/crates/truapi-host-cli/SPEC.md | 7 - rust/crates/truapi-host-cli/src/main.rs | 86 +---------- .../truapi-host-cli/src/script_runner.rs | 141 ------------------ 4 files changed, 5 insertions(+), 234 deletions(-) diff --git a/rust/crates/truapi-host-cli/README.md b/rust/crates/truapi-host-cli/README.md index 3bb43678b..af12e8766 100644 --- a/rust/crates/truapi-host-cli/README.md +++ b/rust/crates/truapi-host-cli/README.md @@ -273,10 +273,7 @@ starter calls `truapi.account.getUserId()` and prints the returned user id. The generated file references an adjacent declaration bundle, so the editor provides completion and type checking for `truapi`, `host`, and `assert` without requiring `@parity/truapi` in a parent npm project. Scripts opened -from an npm project can still import packages installed by that project. Bare -`/script` also adds the declaration and module marker when it reopens a managed -scratch file created by an older host version; explicitly selected scripts are -not rewritten when they live outside the managed scratch directory. +from an npm project can still import packages installed by that project. The TUI temporarily yields the terminal to `$VISUAL`, then `$EDITOR`, or `vi` when neither is set. After the editor exits successfully, the TUI is restored and the saved script runs through the public frame endpoint. Editor diff --git a/rust/crates/truapi-host-cli/SPEC.md b/rust/crates/truapi-host-cli/SPEC.md index 773abad7c..36b6380e1 100644 --- a/rust/crates/truapi-host-cli/SPEC.md +++ b/rust/crates/truapi-host-cli/SPEC.md @@ -841,13 +841,6 @@ declaration beside the scratch file preserves its types across session promotion and removal of older installed binary versions. The script does not emit terminal styling. -When bare `/script` reopens a remembered regular file directly inside the -managed `scripts/` directory whose name matches `script-*.ts`, it refreshes the -adjacent declaration and idempotently adds a missing relative reference or -`export {}` module marker. This migrates scratch files created by older host -versions without replacing their user-edited source. Symlinks and scripts -selected explicitly outside the managed directory are not modified. - Mnemonic-backed ephemeral signing sessions remember a path only for the current process and create scratch files under the system temporary `truapi-host/scripts` directory. diff --git a/rust/crates/truapi-host-cli/src/main.rs b/rust/crates/truapi-host-cli/src/main.rs index 04ec1a8e0..0a1db6f15 100644 --- a/rust/crates/truapi-host-cli/src/main.rs +++ b/rust/crates/truapi-host-cli/src/main.rs @@ -3417,18 +3417,6 @@ fn select_script_to_edit( last_script: &mut Option, ) -> Result { if let Some(script) = last_script.as_ref().filter(|script| script.is_file()) { - let is_managed_scratch = script.parent() == Some(scratch_script_directory) - && script - .file_name() - .and_then(|name| name.to_str()) - .is_some_and(|name| { - name.starts_with("script-") && name.ends_with(".ts") && !name.ends_with(".d.ts") - }) - && std::fs::symlink_metadata(script) - .is_ok_and(|metadata| !metadata.file_type().is_symlink()); - if is_managed_scratch { - script_runner::ensure_scratch_script_types(script)?; - } return Ok(script.clone()); } let script = script_runner::create_scratch_script(scratch_script_directory)?; @@ -3952,62 +3940,6 @@ test -s "$TRUAPI_DEV_COMMAND_TEST_READY_PATH" Ok(()) } - #[test] - fn bare_script_selection_migrates_a_legacy_managed_scratch_script() -> Result<()> { - let temporary = tempfile::tempdir()?; - let scripts = temporary.path().join("scripts"); - std::fs::create_dir_all(&scripts)?; - let legacy = scripts.join("script-legacy.ts"); - std::fs::write( - &legacy, - "#!/usr/bin/env bun\n\nconst value = await truapi.system.getProductContext();\n", - )?; - let mut last_script = Some(legacy.clone()); - - let selected = select_script_to_edit(&scripts, &mut last_script)?; - - assert_eq!( - ( - selected, - std::fs::read_to_string(&legacy)?, - legacy.with_extension("d.ts").is_file(), - ), - ( - legacy, - "#!/usr/bin/env bun\n\n/// \nexport {};\n\nconst value = await truapi.system.getProductContext();\n".to_string(), - true, - ) - ); - Ok(()) - } - - #[cfg(unix)] - #[test] - fn bare_script_selection_does_not_migrate_a_managed_symlink() -> Result<()> { - use std::os::unix::fs::symlink; - - let temporary = tempfile::tempdir()?; - let scripts = temporary.path().join("scripts"); - std::fs::create_dir_all(&scripts)?; - let external = temporary.path().join("external.ts"); - std::fs::write(&external, "console.log('external');\n")?; - let linked = scripts.join("script-linked.ts"); - symlink(&external, &linked)?; - let mut last_script = Some(linked.clone()); - - let selected = select_script_to_edit(&scripts, &mut last_script)?; - - assert_eq!( - ( - selected, - std::fs::read_to_string(&external)?, - linked.with_extension("d.ts").exists(), - ), - (linked, "console.log('external');\n".to_string(), false,) - ); - Ok(()) - } - #[test] fn explicit_script_becomes_the_next_bare_script_selection() -> Result<()> { let temporary = tempfile::tempdir()?; @@ -4021,21 +3953,11 @@ test -s "$TRUAPI_DEV_COMMAND_TEST_READY_PATH" remember_script(Some(temporary.path()), &mut last_script, explicit.clone())?; let selected = select_script_to_edit(&scripts, &mut last_script)?; + assert_eq!(remembered, explicit); + assert_eq!(selected, explicit); assert_eq!( - ( - remembered, - selected, - sessions::session_last_script(temporary.path())?, - std::fs::read_to_string(&explicit)?, - explicit.with_extension("d.ts").exists(), - ), - ( - explicit.clone(), - explicit.clone(), - Some(explicit), - "console.log('product');".to_string(), - false, - ) + sessions::session_last_script(temporary.path())?.as_deref(), + Some(explicit.as_path()) ); Ok(()) } diff --git a/rust/crates/truapi-host-cli/src/script_runner.rs b/rust/crates/truapi-host-cli/src/script_runner.rs index 5f98ca73c..c0cb0f6e8 100644 --- a/rust/crates/truapi-host-cli/src/script_runner.rs +++ b/rust/crates/truapi-host-cli/src/script_runner.rs @@ -115,89 +115,6 @@ pub fn create_scratch_script(directory: &Path) -> Result { create_scratch_script_for_runner(directory, &runner_path()) } -pub fn ensure_scratch_script_types(script: &Path) -> Result<()> { - ensure_scratch_script_types_for_runner(script, &runner_path()) -} - -fn ensure_scratch_script_types_for_runner(script: &Path, runner: &Path) -> Result<()> { - let runner_types = runner_types_path(runner); - let runner_types = fs::read(&runner_types) - .with_context(|| format!("read host-script types {}", runner_types.display()))?; - let types_path = script.with_extension("d.ts"); - fs::write(&types_path, runner_types) - .with_context(|| format!("write script types {}", types_path.display()))?; - let types_name = types_path - .file_name() - .and_then(|name| name.to_str()) - .context("scratch script type filename is not valid UTF-8")?; - let contents = fs::read_to_string(script) - .with_context(|| format!("read scratch script {}", script.display()))?; - let reference = format!(r#"/// "#); - let has_reference = contents.lines().any(|line| line == reference); - let has_module_marker = contents.lines().any(|line| line == "export {};"); - if has_reference && has_module_marker { - return Ok(()); - } - - let line_ending = if contents.contains("\r\n") { - "\r\n" - } else { - "\n" - }; - let updated = if has_reference { - let reference_end = contents - .find(&reference) - .map(|start| start + reference.len()) - .context("scratch script type reference disappeared while migrating")?; - let remainder = contents[reference_end..] - .strip_prefix(line_ending) - .unwrap_or(&contents[reference_end..]); - format!( - "{}{line_ending}export {{}};{line_ending}{remainder}", - &contents[..reference_end] - ) - } else { - let header = if has_module_marker { - reference - } else { - format!("{reference}{line_ending}export {{}};") - }; - if contents.starts_with("#!") { - let shebang_end = contents - .find('\n') - .map(|index| index + 1) - .unwrap_or(contents.len()); - let remainder = contents[shebang_end..] - .strip_prefix(line_ending) - .unwrap_or(&contents[shebang_end..]); - format!( - "{}{line_ending}{header}{line_ending}{line_ending}{remainder}", - &contents[..shebang_end] - ) - } else { - format!("{header}{line_ending}{line_ending}{contents}") - } - }; - let permissions = fs::metadata(script) - .with_context(|| format!("read scratch script metadata {}", script.display()))? - .permissions(); - let parent = script - .parent() - .with_context(|| format!("scratch script has no parent: {}", script.display()))?; - let mut temporary = tempfile::NamedTempFile::new_in(parent) - .with_context(|| format!("create temporary scratch script in {}", parent.display()))?; - temporary - .write_all(updated.as_bytes()) - .with_context(|| format!("write migrated scratch script {}", script.display()))?; - fs::set_permissions(temporary.path(), permissions) - .with_context(|| format!("preserve scratch script permissions {}", script.display()))?; - temporary - .persist(script) - .map_err(|error| error.error) - .with_context(|| format!("replace migrated scratch script {}", script.display()))?; - Ok(()) -} - fn create_scratch_script_for_runner(directory: &Path, runner: &Path) -> Result { fs::create_dir_all(directory) .with_context(|| format!("create script directory {}", directory.display()))?; @@ -547,64 +464,6 @@ console.log('user id', result.value); Ok(()) } - #[test] - fn legacy_scratch_scripts_gain_current_types_without_losing_source() -> Result<()> { - let install = tempfile::tempdir()?; - let runner = install.path().join(PACKAGED_RUNNER); - fs::write(&runner, "packaged runner")?; - fs::write( - install.path().join(PACKAGED_SCRIPT_TYPES), - "declare const packaged: true;\n", - )?; - let scripts = tempfile::tempdir()?; - let script = scripts.path().join("legacy.ts"); - fs::write( - &script, - "#!/usr/bin/env bun\n\nconst value = await truapi.system.getProductContext();\n", - )?; - - ensure_scratch_script_types_for_runner(&script, &runner)?; - ensure_scratch_script_types_for_runner(&script, &runner)?; - - assert_eq!( - ( - fs::read_to_string(&script)?, - fs::read_to_string(script.with_extension("d.ts"))?, - ), - ( - "#!/usr/bin/env bun\n\n/// \nexport {};\n\nconst value = await truapi.system.getProductContext();\n".to_string(), - "declare const packaged: true;\n".to_string(), - ) - ); - Ok(()) - } - - #[test] - fn referenced_scratch_scripts_gain_the_module_marker_once() -> Result<()> { - let install = tempfile::tempdir()?; - let runner = install.path().join(PACKAGED_RUNNER); - fs::write(&runner, "packaged runner")?; - fs::write( - install.path().join(PACKAGED_SCRIPT_TYPES), - "declare const packaged: true;\n", - )?; - let scripts = tempfile::tempdir()?; - let script = scripts.path().join("referenced.ts"); - fs::write( - &script, - "#!/usr/bin/env bun\n\n/// \n\nconst value = await truapi.system.getProductContext();\n", - )?; - - ensure_scratch_script_types_for_runner(&script, &runner)?; - ensure_scratch_script_types_for_runner(&script, &runner)?; - - assert_eq!( - fs::read_to_string(script)?, - "#!/usr/bin/env bun\n\n/// \nexport {};\n\nconst value = await truapi.system.getProductContext();\n" - ); - Ok(()) - } - /// Opening an untyped scratch file recreates the original failure, so a /// broken install must fail before launching the editor. #[test] From f1528739408285349846d4b6649a470d47dff255 Mon Sep 17 00:00:00 2001 From: pg Date: Fri, 28 Aug 2026 16:43:24 +0200 Subject: [PATCH 5/5] Regenerate headless script types --- .../truapi-host-cli/js/script-types.d.ts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/rust/crates/truapi-host-cli/js/script-types.d.ts b/rust/crates/truapi-host-cli/js/script-types.d.ts index e8137955c..e37efcacf 100644 --- a/rust/crates/truapi-host-cli/js/script-types.d.ts +++ b/rust/crates/truapi-host-cli/js/script-types.d.ts @@ -4663,6 +4663,18 @@ export const VrfTranscriptItem: Codec; } +/** Wire discriminant reserved for method-independent protocol errors. **/ +export declare const PROTOCOL_ERROR_ID: 255; +/** The peer rejected an outbound frame because it does not support its API. **/ +export declare class UnsupportedMessageError extends Error { + /** Wire discriminant of the unsupported outbound frame. **/ + readonly discriminant: number; + constructor(discriminant: number); +} +/** Call result returned when the peer does not recognize a request frame. **/ +export type UnsupportedCallError = Extract, { + tag: "Unsupported"; +}>; /** * Handle returned by TrUAPI subscription APIs. **/ @@ -4806,7 +4818,8 @@ export interface RequestParams { payload: Uint8Array; /** * Decode SCALE response payload bytes into the wire `ResultPayload` - * envelope. The transport unwraps the envelope into `ResultAsync`. + * envelope. The transport unwraps the envelope into + * `ResultAsync`. **/ decodeResponse: (payload: Uint8Array) => ResultPayload; } @@ -4831,7 +4844,8 @@ export interface SubscribeRawParams { **/ onInterrupt?: (payload: Uint8Array) => void; /** - * Called when the underlying provider closes while the subscription is active. + * Called when a transport-level error or unsupported start frame terminates + * the subscription. **/ onClose?: (error: Error) => void; } @@ -4874,7 +4888,7 @@ export interface TrUApiTransport { /** * Send a one-shot request and resolve with the typed Ok/Err outcome. **/ - request(params: RequestParams): ResultAsync; + request(params: RequestParams): ResultAsync; /** * Start a subscription and return a handle that can stop it. **/