diff --git a/Cargo.lock b/Cargo.lock index 3fd3b5a09..2a3a0e2f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5102,6 +5102,7 @@ dependencies = [ "anyhow", "arboard", "async-trait", + "base64", "bip39", "clap", "crossterm", diff --git a/hosts/dotli b/hosts/dotli index 29ef38b6c..3592073c2 160000 --- a/hosts/dotli +++ b/hosts/dotli @@ -1 +1 @@ -Subproject commit 29ef38b6c144b2048c17f9404878801b1492fed0 +Subproject commit 3592073c29121a8fdaabdfce2314dcded42e2a46 diff --git a/ios/truapi-host/Sources/TrUAPIHost/truapi_platform.swift b/ios/truapi-host/Sources/TrUAPIHost/truapi_platform.swift index 9ae61ebfc..8aba9428a 100644 --- a/ios/truapi-host/Sources/TrUAPIHost/truapi_platform.swift +++ b/ios/truapi-host/Sources/TrUAPIHost/truapi_platform.swift @@ -1118,7 +1118,7 @@ public struct SessionUiInfo: Equatable, Hashable { */ public var publicKey: Bytes32 /** - * Wallet identity account id used for People-chain username lookup. + * Wallet identity account id used for the dotNS username lookup on Asset Hub. */ public var identityAccountId: Bytes32? /** @@ -1139,11 +1139,11 @@ public struct SessionUiInfo: Equatable, Hashable { */ public var peerStatementAccountId: Bytes32? /** - * Short username from the People-chain identity record. + * Short username from the dotNS identity record on Asset Hub. */ public var liteUsername: String? /** - * Fully qualified username from the People-chain identity record. + * Fully qualified username from the dotNS identity record on Asset Hub. */ public var fullUsername: String? @@ -1154,7 +1154,7 @@ public struct SessionUiInfo: Equatable, Hashable { * 32-byte sr25519 root public key of the active session. */publicKey: Bytes32, /** - * Wallet identity account id used for People-chain username lookup. + * Wallet identity account id used for the dotNS username lookup on Asset Hub. */identityAccountId: Bytes32?, /** * X25519 public key addressing this identity in chat. Public counterpart @@ -1171,10 +1171,10 @@ public struct SessionUiInfo: Equatable, Hashable { * device discriminator; use [`Self::device_enc_public_key`] for that. */peerStatementAccountId: Bytes32?, /** - * Short username from the People-chain identity record. + * Short username from the dotNS identity record on Asset Hub. */liteUsername: String?, /** - * Fully qualified username from the People-chain identity record. + * Fully qualified username from the dotNS identity record on Asset Hub. */fullUsername: String?) { self.publicKey = publicKey self.identityAccountId = identityAccountId diff --git a/js/packages/truapi-host/src/runtime.ts b/js/packages/truapi-host/src/runtime.ts index a8ca98fe6..dde284138 100644 --- a/js/packages/truapi-host/src/runtime.ts +++ b/js/packages/truapi-host/src/runtime.ts @@ -81,7 +81,7 @@ export interface ProductRuntimeConfig { /** Platform or operating-system version. */ version?: string; }; - /** People-chain configuration used for identity lookup. */ + /** People-chain configuration used for statement-store SSO. */ people: { /** People-chain genesis hash. */ genesisHash: string | Uint8Array; @@ -91,6 +91,11 @@ export interface ProductRuntimeConfig { /** Bulletin-chain genesis hash. */ genesisHash: string | Uint8Array; }; + /** Asset Hub configuration used to resolve session usernames from dotNS. */ + assetHub: { + /** Asset Hub genesis hash. */ + genesisHash: string | Uint8Array; + }; /** Wallet pairing configuration. */ pairing: { /** URI scheme used for wallet pairing deeplinks. */ diff --git a/js/packages/truapi-host/src/web/worker-provider.test.ts b/js/packages/truapi-host/src/web/worker-provider.test.ts index 6b73524f3..4fc18d4a3 100644 --- a/js/packages/truapi-host/src/web/worker-provider.test.ts +++ b/js/packages/truapi-host/src/web/worker-provider.test.ts @@ -96,6 +96,10 @@ function runtimeConfig( genesisHash: "0xbbcccc1cbe333151b8ed63b17e9e0dec61ee53b57296f1fbe2d161ae3e6fb4dc", }, + assetHub: { + genesisHash: + "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + }, pairing: { deeplinkScheme: "polkadotapp", }, diff --git a/js/packages/truapi-host/src/worker-runtime.ts b/js/packages/truapi-host/src/worker-runtime.ts index 3062a4611..4cb318e52 100644 --- a/js/packages/truapi-host/src/worker-runtime.ts +++ b/js/packages/truapi-host/src/worker-runtime.ts @@ -108,7 +108,7 @@ interface WorkerChainConnection { * Worker-side half of the host chain-connect bridge. * * The Rust core runs in this worker but owns no socket. When it needs chain - * access (chainHead v1 for People-chain identity / statement-store SSO) it + * access (chainHead v1 for dotNS identity on Asset Hub / statement-store SSO) it * calls this; the actual transport lives on the host main thread and is reached * over postMessage. The data crossing here is JSON-RPC strings, not SCALE: only * the product<->core wire is SCALE. @@ -117,7 +117,7 @@ interface WorkerChainConnection { * +-------------------+ SCALE +--------------------------+ +--------------------------------+ * | Product (iframe) |<------->| truapi-server WASM core | | host.connect() (ChainProvider) | * | speaks TrUAPI | frames | chainHead v1, SSO, | | host-owned JSON-RPC transport | - * | never sees chains | | People-chain identity | | remote RPC, native client, ... | + * | never sees chains | | dotNS identity (AH) | | remote RPC, native client, ... | * +-------------------+ +--------------------------+ +--------------------------------+ * | ^ JSON-RPC strings (not SCALE) ^ | * chainConnect() | | onResponse(json) connect | | responses() diff --git a/playground/src/lib/example-helpers.ts b/playground/src/lib/example-helpers.ts index 47e436ccd..f624522fc 100644 --- a/playground/src/lib/example-helpers.ts +++ b/playground/src/lib/example-helpers.ts @@ -1,6 +1,6 @@ import { Observable } from "rxjs"; import { err, ok, type Result } from "neverthrow"; -import { PASEO_NEXT_V2_INDIVIDUALITY } from "@parity/truapi"; +import { PASEO_NEXT_V2_ASSET_HUB } from "@parity/truapi"; import { AccountId, Blake2128Concat, @@ -51,7 +51,10 @@ export type BuildCreateTransactionPayload = (opts: { callData: HexString; }) => Promise>; -const usernameOwnerOfStorage = Storage("Resources")("UsernameOwnerOf", [ +// Lite usernames are keyed by their dotted label ("alice.01") on the Asset +// Hub gateway pallet. Full-person ownership lives contract-side as H160 only. +// Name→account resolution therefore covers lite usernames. +const liteLabelOwnerStorage = Storage("DotnsGateway")("LiteLabelOwner", [ Bytes(), Blake2128Concat, ]); @@ -113,7 +116,7 @@ export function createAccountIdForDotNsUsername( return err(new Error("DotNS username is empty")); } - const key = usernameOwnerOfStorage.enc( + const key = liteLabelOwnerStorage.enc( new TextEncoder().encode(dotNsUsername), ) as HexString; @@ -137,7 +140,7 @@ export function createAccountIdForDotNsUsername( switch (item.tag) { case "Initialized": { const result = await truapi.chain.getHeadStorage({ - genesisHash: PASEO_NEXT_V2_INDIVIDUALITY.genesis, + genesisHash: PASEO_NEXT_V2_ASSET_HUB.genesis, followSubscriptionId: sub.subscriptionId, hash: item.value.finalizedBlockHashes[0], items: [{ key, queryType: "Value" }], @@ -188,7 +191,7 @@ export function createAccountIdForDotNsUsername( const sub = truapi.chain .followHeadSubscribe({ request: { - genesisHash: PASEO_NEXT_V2_INDIVIDUALITY.genesis, + genesisHash: PASEO_NEXT_V2_ASSET_HUB.genesis, withRuntime: false, }, }) diff --git a/rust/crates/truapi-codegen/tests/golden/host-callbacks.ts b/rust/crates/truapi-codegen/tests/golden/host-callbacks.ts index d31dc2f1a..ef084e64e 100644 --- a/rust/crates/truapi-codegen/tests/golden/host-callbacks.ts +++ b/rust/crates/truapi-codegen/tests/golden/host-callbacks.ts @@ -370,7 +370,7 @@ export interface SessionUiInfo { publicKey: Bytes32; /** - * Wallet identity account id used for People-chain username lookup. + * Wallet identity account id used for the dotNS username lookup on Asset Hub. */ identityAccountId?: Bytes32; @@ -395,12 +395,12 @@ export interface SessionUiInfo { peerStatementAccountId?: Bytes32; /** - * Short username from the People-chain identity record. + * Short username from the dotNS identity record on Asset Hub. */ liteUsername?: string; /** - * Fully qualified username from the People-chain identity record. + * Fully qualified username from the dotNS identity record on Asset Hub. */ fullUsername?: string; } diff --git a/rust/crates/truapi-host-cli/Cargo.toml b/rust/crates/truapi-host-cli/Cargo.toml index c07962f5e..8c5fe62d4 100644 --- a/rust/crates/truapi-host-cli/Cargo.toml +++ b/rust/crates/truapi-host-cli/Cargo.toml @@ -19,6 +19,7 @@ truapi-server = { path = "../truapi-server" } anyhow = "1" arboard = { version = "3.6.1", default-features = false } async-trait = "0.1" +base64 = "0.22" bip39 = { version = "2", features = ["rand"] } clap = { version = "4", features = ["derive", "env"] } crossterm = { version = "0.29", features = ["event-stream"] } diff --git a/rust/crates/truapi-host-cli/README.md b/rust/crates/truapi-host-cli/README.md index 2dae02e58..b10c001d1 100644 --- a/rust/crates/truapi-host-cli/README.md +++ b/rust/crates/truapi-host-cli/README.md @@ -21,7 +21,8 @@ One binary, `truapi-host`: | --- | --- | | `pairing-host` | Seedless host: serves product frames, emits pairing deeplinks, and can run product scripts. | | `signing-host` | Wallet-local host: owns signer identity, can run product scripts, accepts pairing deeplinks, registers statement allowance on-chain, signs. | -| `identity-check` | Probe the root and canonical `uid.dot` identity account for a registered username. | +| `identity-check` | Probe the root and canonical `uid.dot` identity account for a registered username (read from the dotNS contracts on Asset Hub). | +| `register-name` | Register a full-person username via `DotnsGateway.register_name` on Asset Hub, linked to a lite username or standalone with a chat key. | | `alloc-check` | Diagnose (or `--submit`) on-chain statement-store allowance: ring membership, chosen slot, and the `set_statement_store_account` extrinsic. On a full period it prints each occupied slot's age and which one would be replaced. | | `pgas-check` | Diagnose (or `--submit`) an Asset Hub PGAS allowance claim: ring membership on People, whether Asset Hub has imported that ring revision, the day's first unclaimed slot, and the `Pgas.claim_pgas` extrinsic. | @@ -174,7 +175,9 @@ New auto-managed accounts use the session name as their Lite username prefix; characters other than lowercase letters are omitted. For example, session `pgtest` creates usernames beginning with `pgtest`. An explicit `--lite-username-prefix` takes precedence, and `default` retains the historical -`headless` prefix. +`headless` prefix. `--reserved-username