Skip to content

/v1/accounts/onboard does not bind UAID to dataspace #5528

@nvzhu

Description

@nvzhu

Issue: /v1/accounts/onboard does not bind UAID to dataspace

Environment

  • Branch: i23
  • Commit: 3b9f581e4
  • Network: Local kagami localnet (4 peers)
  • Date: 2026-01-19

Summary

Accounts created via the /v1/accounts/onboard endpoint cannot perform transactions because the UAID is not bound to any dataspace. The onboard handler creates the account with a UAID but does not add the necessary dataspace binding, causing all subsequent transactions to be rejected with UAID not bound to dataspace.

Steps to Reproduce

# 1. Start localnet with onboarding enabled
cd /tmp/2iroha-localnet
IROHAD_BIN=/path/to/irohad ./start.sh

# 2. Register a new account via onboard
curl -X POST http://127.0.0.1:8080/v1/accounts/onboard \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "testuser",
    "account_id": "ed0120AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@wonderland"
  }'

# 3. Check UAID bindings (shows empty dataspaces)
iroha --config client.toml space-directory bindings fetch \
  --uaid "uaid:<returned-uaid>"

# 4. Attempt a transfer using the new account
# Result: Transaction rejected with "UAID not bound to dataspace"

Expected Behavior

After successful onboarding, the account should be able to perform basic transactions (transfers) without requiring manual manifest/dataspace binding setup.

Option A: Onboard should automatically bind UAID to a default dataspace (e.g., dataspace 0 "universal"):

// In handle_v1_accounts_onboard after Register::account
let bind_instruction = BindUaidToDataspace::new(uaid, DataSpaceId::new(0));
builder.with_instructions([register, bind_instruction]);

Option B: Onboard should accept an optional dataspace parameter:

{
  "alias": "testuser",
  "account_id": "ed0120...@wonderland",
  "dataspace": 0
}

Actual Behavior

  1. Onboard creates the account with UAID
  2. UAID has no dataspace bindings (dataspaces: [])
  3. Any transaction from this account is rejected:
WARN iroha_core::queue: rejecting transaction: UAID not bound to dataspace
     uaid=uaid:2d8a79... dataspace=0 authority=34mSYn...@wonderland

Code Analysis

Onboard handler (crates/iroha_torii/src/routing.rs:27847-27927):

let register = Register::account(
    dm::Account::new(account_id.clone())
        .with_metadata(metadata)
        .with_uaid(Some(uaid)),  // UAID is set
);
// But NO dataspace binding instruction is added

Queue validation (crates/iroha_core/src/queue.rs:1569-1589):

let bound = state_view
    .world()
    .uaid_dataspaces()
    .get(&uaid)
    .is_some_and(|bindings| bindings.is_bound_to(dataspace_id, authority));
if !bound {
    // Transaction rejected here
    return Err(Error::UaidNotBound { uaid, dataspace: dataspace_id });
}

Impact

  • Mobile SDKs (iOS/Android): Cannot use onboard for user registration in CBDC apps
  • User onboarding flow: Broken without manual governance intervention
  • Testing: Requires using genesis accounts instead of onboarded accounts

Suggested Solutions

  1. Auto-bind to default dataspace: Add configuration option torii.onboarding.default_dataspace that automatically binds new UAIDs
  2. Accept dataspace in request: Extend AccountOnboardingRequestDto with optional dataspace: u64 field
  3. Wildcard binding: Create a "bootstrap" binding that allows basic operations until proper manifest is published

Related

  • Space Directory documentation: docs/space-directory.md
  • Manifest lifecycle: crates/iroha_core/src/smartcontracts/isi/space_directory.rs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions