diff --git a/cip-0103/cip-0103.md b/cip-0103/cip-0103.md
new file mode 100644
index 0000000..2aa3a0c
--- /dev/null
+++ b/cip-0103/cip-0103.md
@@ -0,0 +1,508 @@
+# CIP-0103: dApp Standard
+
+
+ CIP: 0103
+ Title: dApp Standard
+ Author: Digital Asset (Marc Juchli), PixelPlex (Alexey Chyker, Eugene Birski)
+ Status: Proposed
+ Type: Standards Track
+ Created: 2025-11-28
+ License: CC0-1.0
+ Post-History: https://lists.sync.global/g/cip-discuss/topic/cip_tbd_dapp_api_towards/115892502
+
+
+## Abstract
+
+This proposal introduces a vendor-neutral **dApp API** that decouples network connectivity and key management from decentralized applications, while providing a standardized set of primitives for interacting with the Canton Network.
+
+Using the dApp API, users can access any application with a validator and signing provider of their choice. In this model, dApp clients operate in conjunction with **Wallets**, which implement the dApp API, are trusted by the user, and enforce authorization to guard against malicious requests from untrusted dApps.
+
+The design emphasizes a **minimal, interoperable surface** with strict, unambiguous semantics for requests, responses, and errors, while remaining flexible enough to support diverse Wallet architectures and deployment models.
+
+As a result, any dApp client can seamlessly interoperate with any Wallet.
+
+## Copyright
+
+This CIP is licensed under CC0-1.0: [Creative Commons CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/)
+
+## Motivation
+
+Today, dApp clients built for the Canton Network are tightly coupled to specific network, key-management, and wallet integrations. The lack of a unified standard forces developers to repeatedly reimplement similar patterns, limits interoperability, and constrains user choice. Users cannot easily select the validator or signing provider they trust, and app developers must maintain multiple ad-hoc integration paths. This fragmentation introduces unnecessary friction, increases integration effort, and elevates security risks.
+
+Existing interfaces, such as the gRPC and JSON Ledger APIs, provide low-level protocol access but do not address higher-level concerns: standard signing flows, user consent, cross-origin communication, or consistent error semantics. Without a formal standard, wallets and applications cannot reliably interoperate, preventing a healthy ecosystem and hindering modular innovation.
+
+To address these challenges, the **dApp API** introduces a **vendor-neutral, transport-agnostic framework** for Canton-native dApps. By defining a shared interface for ledger interaction, transaction submission, and message signing, the API decouples dApp clients from wallet implementations while preserving security guarantees. Users can connect through any validator and sign using the method of their choice, while wallets enforce authorization to prevent misbinding and phishing from untrusted dApps. The API is also designed to accommodate future wallets, custody solutions, and deployment models, ensuring that new implementations can interoperate seamlessly with existing dApps and infrastructure.
+
+The API is designed to decouple the following three kinds of services:
+
+1. **Wallet and custody solution providers**
+ Responsible for identity, authorization, and signing. They implement the dApp API to enable secure user interaction with dApps.
+2. **User-facing dApps**
+ Expose on-ledger actions (transfers, settlements, governance, etc.) through web or mobile interfaces.
+3. **Application backends**
+ Programmatically create, query, and manage contracts and transactions on the Canton ledger.
+
+The design emphasizes the following characteristics:
+
+- **Transport-agnostic:**
+ Any dApp (client) can interact with any wallet (server), independent of implementation or transport.
+- **Signing-provider agnostic:**
+ Supports internal and external signing, regardless of the private key's location.
+- **Multi-network support:**
+ Users may connect to any validator node and synchronizer supported by their wallet
+- **Minimal operation set:**
+ Standardizes primitives for ledger reads, ledger writes, and message signing.
+- **Standardized error model:**
+ Standardized error codes ensure predictable control flow and consistent telemetry.
+- **Secure:**
+ Private keys remain within the signing provider; user authorization is enforced, and the attack surface is minimized.
+
+This CIP draws inspiration from widely adopted standards such as **EIP-1193**, while addressing Canton-specific requirements: privacy-preserving participants, multi-party workflows, and synchronized settlement. The dApp API can also be **wrapped in a provider object**, similar to Ethereum, allowing dApps to interact with a Wallet through a familiar interface. By providing a portable, secure, and interoperable foundation, the dApp API enables any dApp client to reliably interact with any wallet, reduces developer friction, improves user security, and supports a robust, modular Canton ecosystem.
+
+
+## Specification
+
+### Definitions
+
+This section defines the terms used normatively throughout the specification. Each term is scoped to this CIP and, unless stated otherwise, applies to all methods, transports, and UX requirements. The goal is to ensure unambiguous meaning so that independent wallets and dApps interpret the interface consistently.
+
+| **Term** | **Definition** | **Notes** |
+| --- | --- | --- |
+| Client | Invokes RPC methods defined by the dApp API | Client adheres to the JSON-RPC specification, but defines the transport method |
+| dApp | Decentralized Application.
The client side (typically a web app) consumes the dApp API. | Application with at least part of the backend and database hosted on a decentralized infrastructure, e.g., as a smart contract on Canton, combined with a client such as a UI frontend.
Given the nature of the topic, this document treats the dApp as primarily the UI. |
+| Network | Network access parameters | Uniquely defined by: (Validator, Synchronizer, Authentication details) |
+| Wallet | Provides the dApp API. Middleware between the client and the network, as well as the signing provider. | Implementation details are out of scope; MUST honor methods/events, UX, and error codes |
+
+### Provider API
+
+The Provider API defines a set of methods that enable the uniform usage of the dApp API (see below). The methods in this interface are an exact replica of the Provider API defined in [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193).
+
+Below is the interface description in Typescript. Interface definitions in other languages that replicate the methods are equally valid:
+
+```typescript
+type EventListener = (...args: T[]) => void
+
+type RequestParams = unknown[] | Record
+
+interface RequestPayload {
+ method: string
+ params?: RequestParams
+}
+
+interface Provider {
+ request(args: RequestPayload): Promise
+ on(event: string, listener: EventListener): Provider
+ emit(event: string, ...args: T[]): boolean
+ removeListener(
+ event: string,
+ listenerToRemove: EventListener
+ ): Provider
+}
+```
+
+Using the interface above, dApp API requests are issued by specifying the appropriate `method` and corresponding `params` as defined in this specification. Similarly, dApp API events can be consumed by registering a listener for the corresponding `event`.
+
+#### Error Types
+
+It is the Provider’s responsibility to enforce a consistent error format. As noted above, this CIP adopts the conventions defined in EIP-1193, with error structure and codes further aligned with [EIP-1474](https://eips.ethereum.org/EIPS/eip-1474#error-codes):
+
+```typescript
+interface ProviderRpcError extends Error {
+ message: string
+ code: number
+ data?: unknown
+}
+```
+
+Error member included on the response object **MUST** be an object containing a `code` member and a descriptive `message` member.
+
+In addition to defining the error format, this CIP incorporates the error codes specified in EIP-1474. To ensure consistency with established ecosystem conventions, the following table enumerates all supported error codes and their corresponding messages:
+
+| **Code** | **Message** | **Meaning** | **EIP** |
+| --- | --- | --- | --- |
+| 4001 | User Rejected Request | The user rejected the request. | EIP-1193 |
+| 4100 | Unauthorized | The requested method and/or account has not been authorized by the user. | EIP-1193 |
+| 4200 | Unsupported Method | The Provider does not support the requested method. | EIP-1193 |
+| 4900 | Disconnected | The Provider is disconnected from all chains. | EIP-1193 |
+| 4901 | Chain Disconnected | The Provider is not connected to the requested chain. | EIP-1193 |
+| \-32700 | Parse error | Invalid JSON | EIP-1474 |
+| \-32600 | Invalid request | JSON is not a valid request object | EIP-1474 |
+| \-32601 | Method not found | Method does not exist | EIP-1474 |
+| \-32602 | Invalid params | Invalid method parameters | EIP-1474 |
+| \-32603 | Internal error | Internal JSON-RPC error | EIP-1474 |
+| \-32000 | Invalid input | Missing or invalid parameters | EIP-1474 |
+| \-32001 | Resource not found | Requested resource not found | EIP-1474 |
+| \-32002 | Resource unavailable | Requested resource not available | EIP-1474 |
+| \-32003 | Transaction rejected | Transaction creation failed | EIP-1474 |
+| \-32004 | Method not supported | Method is not implemented | EIP-1474 |
+| \-32005 | Limit exceeded | Request exceeds defined limit | EIP-1474 |
+
+#### Provider Discovery
+
+A dApp **MAY** allow users to select from multiple available providers. While multiple providers may advertise their availability, the mechanism for such announcements is **out of scope** for this CIP, which focuses on the dApp API exposed by a single provider. We expect the mechanism for dealing with multiple providers to be specified in a future CIP.
+
+### dApp API
+
+The **dApp API** defines a standardized, transport-agnostic interface that enables decentralized applications (dApps) to securely interact with the Canton Network via Wallets. It decouples dApps from wallet implementations, supports multiple network configurations, and enforces consistent signing flows, reducing developer friction and improving user security. By providing uniform primitives for ledger access, transaction submission, and message signing, the API ensures interoperability between independently developed dApps and Wallets.
+
+The ground truth for the dApp API is maintained in the Splice Wallet repository in a machine-readable form. The methods and events listed in this document represent those that **MUST** be implemented by Wallet Providers and provide a convenient summary of the state of the API at the time of writing for readers of the CIP.
+
+The dApp API exists in two variants, each targeting a different deployment model and interaction pattern:
+
+1. **[Synchronous dApp API](https://github.com/hyperledger-labs/splice-wallet-kernel/blob/main/api-specs/openrpc-dapp-api.json)** (aka Sync dApp API) – Intended for clients with direct access to a Wallet, such as browser extensions or local Wallets. Methods and events execute in a request–response fashion, enabling immediate ledger reads, transaction preparation, and signing flows.
+
+
+2. **[Asynchronous dApp API](https://github.com/hyperledger-labs/splice-wallet-kernel/blob/main/api-specs/openrpc-dapp-remote-api.json)** (aka Async dApp API) – Designed for server-side Wallets or Wallets deployed as services that cannot support blocking calls or direct synchronous interactions. This variant decomposes operations requiring user interaction into multi-phase workflows, often exposing `userUrl`’s to allow users to complete actions asynchronously (for example, by interacting with a UI) while the client process continues to wait for an event to be emitted (as a result of the user interaction).
+
+Clients such as frontends that work against the sync dApp API **SHOULD** also work against a server exposing the async dApp API. This ensures that applications can support both local and remote Wallet configurations without changing core business logic.
+We expect frontends to do so by implementing the sync dApp API by relaying calls to an async dApp API server. See the [reference dApp SDK implementation](#references) for a drop-in solution.
+
+#### Synchronous dApp API
+
+The **Synchronous dApp API** variant is intended for clients that have direct access to a Wallet, such as browser extensions, desktop applications, or mobile Wallets. In this model, methods and events are executed in a standard request–response fashion, allowing dApps to perform ledger reads, transaction preparation, and signing operations immediately and deterministically.
+
+Wallet Providers implementing this variant **MUST** support all listed methods and events, ensuring consistent behavior and error semantics across deployments. This variant is the canonical choice for end-user applications, providing a familiar synchronous programming model and minimizing latency between user actions and dApp responses.
+
+Overview of supported methods:
+
+| **Method** | **Output** | **Notes** |
+| --- | --- | --- |
+| connect | ConnectResult | Establishes a connection to the server (e.g. Wallet) |
+| disconnect | void | Closes the session between the client and the provider |
+| isConnected | ConnectResult | Indicates connectivity to the server (e.g. Wallet) |
+| status | StatusEvent | Contains information regarding the connected Wallet and Network |
+| getActiveNetwork | Network | Details of the connected network |
+| listAccounts | Account\[\] | Lists all Accounts |
+| getPrimaryAccount | Account | Single Account that is subject to the dApp |
+| signMessage | string | Signs an arbitrary string |
+| prepareExecute | Void | Prepares, signs, and executes the commands |
+| ledgerApi | string | Proxies Ledger API |
+
+Overview of supported events:
+
+| **Event** | **Paylaod** | **Notes** |
+| --- | --- | --- |
+| accountsChanged | AccountsChangedEvent | Contains all the accounts known to the provider and states which one is currently the primary account. |
+| statusChanged | StatusEvent | Informs about the status of the provider the client is connected to; for example, whether or not the user is authenticated and/or connected to a network. |
+| txChanged | TxChangedEvent | Announces changes to the lifecycle of initiated transactions. |
+
+The following sections provide details on each endpoint.
+
+##### connect
+
+Returns a `ConnectResult` with `isConnected = true` if authentication between the user client and the dApp API server has been successfully established; otherwise, returns a `ConnectResult` with `isConnected = false`.
+Additionally, the response **MAY** include an `isNetworkConnected` field (optionally accompanied by an error reason) indicating whether the dApp API server is currently connected to a Canton network.
+- Network connection is considered to be established if an unauthenticated ledger endpoint, such as `/v2/version`, can be accessed
+
+If the user client does not have an active session with the server, the user login flow **MUST** be executed before a response is returned.
+
+```typescript
+// ConnectResult
+{
+ isConnected: boolean,
+ reason?: string
+ isNetworkConnected?: boolean,
+ networkReason?: string
+}
+```
+
+##### isConnected
+
+Same as `connect`, but does not initialize the login.
+
+##### disconnect
+
+Closes the connection between the user client and the dApp API server. As a result, the user session, involving the access token, is being invalidated on the server. In addition, the `statusChanged` event **MAY** be emitted as an asynchronous confirmation sent back to the dApp.
+
+##### status
+
+Returns the connectivity status as per `connect` and additional information regarding the connection and the dApp API server properties. The property `kernel` holds a unique identifier of the server (e.g., the Wallet component) and indicates the deployment type in the `clientType` field. In addition, the optional fields `network` and `session` **MAY** carry information about the user's session and the network to which the connection is established. However, if returned, the `networkId` **SHOULD** be [CAIP-2](https://chainagnostic.org/CAIPs/caip-2) compliant, e.g., `canton:da-mainnet`.
+
+```typescript
+// StatusEvent
+{
+connection: ConnectResult,
+provider: Provider,
+network?: Network,
+session?: Session
+}
+
+// Provider
+{
+ id: string,
+ version: string, // dApp API version
+ providerType: Enum[browser,desktop,mobile,remote]
+}
+
+// Network
+{
+ networkId: string, // CAIP-2
+ ledgerApi?: string
+ accessToken?: string,
+}
+
+// Session
+{
+ accessToken: string,
+ userId: string
+}
+```
+
+##### getActiveNetwork
+
+Returns the network (same type as seen in `status`) with which the user has established a connection via the dApp server.
+
+##### listAccounts
+
+Return a list of accounts the user has access to. Specifically, an account is a Canton `party` with additional metadata, as well as information about its status and the network where its private data can be accessed. In addition, the user chooses to use a given account as the `primary` account (and the corresponding network) in the context of the current dApp session.
+
+```typescript
+// Account
+{
+ primary: boolean,
+ partyId: string,
+ status: Enum[initializing, allocated],
+ hint: string,
+ publicKey: string,
+ namespace: string,
+ networkId: string,
+ signingProviderId: string
+}
+```
+
+##### getPrimaryAccount
+
+Returns the single account set to `primary`, provided the user has access to at least one account. See `listAccounts` above for type information.
+
+Note: the Wallet Provider **MUST** define (or give the user the controls to define) exactly one party as the primary party, provided
+
+##### signMessage
+
+Takes an arbitrary `string` and returns the signature of the message received. The Wallet Provider **MUST** use the private key corresponding to the account with the `primary` property set to `true`, or, alternatively, give the user the option to sign using another account’s private key. Naturally, the public key of the same party can be used to verify the signature.
+
+##### prepareExecute
+
+Provides an abstraction over the prepare, sign, and execute steps required to submit a Daml transaction to a Canton participant node. Thereby, the Wallet Provider **SHOULD** support internal and external parties.
+
+The request argument is compatible with the [JsPrepareSubmissionRequest](https://github.com/digital-asset/canton/blob/37b1b011fc52e3dc369f4bd72e334a011e31c079/community/ledger/ledger-json-api/src/test/resources/json-api-docs/openapi.yaml#L5006-L5127) type found in the JSON ledger API.
+
+This method returns void, and once the commands are passed the preparation stage, the Wallet provider **MUST** emit an `txChanged` event.
+
+##### ledgerApi
+
+Enables submitting requests to the validator node's JSON Ledger API associated with the account. The requests are authenticated to read as the party associated with the account. The request parameter defines the method, resource, and, depending on the method, a body. The body and response are generic and correspond to the expected Ledger API type, encoded as a JSON `string`.
+
+```typescript
+// LedgerApiRequest
+{
+ requestMethod: string, // GET, POST, PUT, DELETE
+ resource: string,
+ body: string
+}
+
+// LedgerApiResponse
+{
+ response: string
+}
+```
+
+##### accountsChanged
+
+Carries a list of accounts (see `listAccounts` for type definition) that the user has access to. A wallet provider **MUST** at least include all accounts that changed.
+
+##### statusChanged
+
+This event results from changes made by the user related to network connectivity and/or authentication. The event carries a payload of type `StatusEvent` as described in the `status` method.
+
+##### txChanged
+This event is emitted along the lifecycle of a command submission (aiming to result in an executed ledger event). Depending on the change or outcome, the event payload will contain one of the following types:
+
+```typescript
+// TxChangedPendingEvent
+{
+ status: Enum[pending],
+ commandId: string
+}
+
+// TxChangedSignedEvent
+{
+ status: Enum[signed],
+ commandId: string
+ payload: {
+ signature: string,
+ signedBy: string,
+ party: string
+ }
+}
+
+// TxChangedExecutedEvent
+{
+ status: Enum[executed],
+ commandId: string
+ payload: {
+ updateId: string,
+ completionOffset: number
+ }
+}
+
+// TxChangedFailedEvent
+{
+ status: Enum[failed],
+ commandId: string
+}
+```
+
+#### Asynchronous dApp API
+
+The **Asynchronous dApp API** variant is designed for server-side Wallets or Wallets deployed as remote services, where synchronous interactions are not feasible due to transport limitations (e.g., HTTP) or the need for multi-step user authorization. The async dApp API mirrors the sync dApp API in a one-to-one fashion exception for operations that require user interaction, e.g., login or transaction approval. These are decomposed into multi-step workflows.
+
+For such multi-step operations, Wallet Providers **MUST** return a `userUrl` that directs the user to complete the required action, and **MUST** emit the corresponding event once the action is finalized. This variant of the dApp API enables backends and server-side applications to integrate with Canton Wallets while avoiding blocking network calls.
+
+**Overview of affected methods compared to the Synchronous dApp API above:**
+
+| **Method** | **Output** | **Notes** |
+| --- | --- | --- |
+| connect | {
..ConnectResult, userUrl: string
} | If no prior connection is established, a \`userUrl\` is returned that points the user to a login facility. After a successful login, an \`connected\` event **\*\*MUST\*\*** be submitted. |
+| prepareExecute | { userUrl: string } | A \`userUrl\` is returned, pointing the user to a review facility to approve or decline the signing of the submitted commands. A \`txChanged\` **\*\*MUST\*\*** be emitted no later than completing the \`prepare\` phase. |
+
+Additional event:
+
+| **Event** | **Payload** | **Notes** |
+| --- | --- | --- |
+| connected | StatusEvent | Contains the same payload as \`statusChanged\` but is only emitted as part of the login flow. |
+
+This variant ensures that operations that normally require synchronous blocking can proceed in a non-blocking, multi-step manner using userUrl handoffs and corresponding events.
+
+## API Evolution
+
+This section defines how the dApp API and its associated artifacts are expected to evolve following the acceptance of this CIP.
+
+### Versioning
+
+The API artifacts defined by this CIP (OpenRPC specifications and interface definitions) **MUST** be versioned. The authors of this CIP will publish the first stable version 1.0.0 of the API upon acceptance of the CIP. Published artifacts will be maintained in the `/api-specs/` directory in the [splice-wallet-kernel](https://github.com/hyperledger-labs/splice-wallet-kernel/tree/main/api-specs) repository.
+
+Apps **SHOULD** check upon connecting whether the version is recent enough to support their use of the API.
+
+### Categories of Changes
+
+API changes fall into three categories:
+
+#### Editorial Changes
+
+Clarifications, wording updates, and other non-semantic improvements **MAY** be made at any time. These changes neither require a new API version nor a CIP amendment.
+
+#### Non-Breaking Changes
+
+Backward-compatible modifications – such as adding optional fields or new methods that do not affect existing behavior – **MAY** be introduced in coordination with other wallet providers.
+Such changes **SHOULD** result in a new minor version of the API artifacts, but do not require an amendment to this CIP.
+
+#### Breaking Changes
+
+Modifications that alter existing semantics, remove functionality, or introduce new mandatory behavior **MUST** be treated as breaking. Breaking changes **REQUIRE** an amendment to this CIP and the publication of a new minor version of the API artifacts.
+
+### Guiding Principles
+
+The evolution of the API **SHOULD** prioritize:
+- Long-term interoperability across independently developed wallets and dApps
+- Stability of published versions
+- Minimization of breaking changes
+- Predictable upgrade paths for implementers
+
+This CIP governs the lifecycle of the dApp API; any change that alters normative behavior falls under the processes defined above.
+
+## Rationale
+
+The design of the dApp API is motivated by the need to decouple dApps from wallet implementations, reduce fragmentation, and enable a healthy multi-provider ecosystem. Prior to this CIP, dApps were forced to integrate directly with ledger endpoints, bespoke wallet connectors, or environment-specific SDKs. This created tight coupling between dApps, network transports, and key-management architectures, preventing interoperability and limiting user choice.
+
+### Alignment with existing ecosystem standards
+
+A major design goal was to converge with established practices in other decentralized ecosystems. The dApp API adopts the Provider abstraction from EIP-1193 and the error semantics defined by EIP-1474. This ensures that developers already familiar with Ethereum’s provider model can integrate with Canton using well-understood concepts such as:
+- A single Provider object exposed to the client
+- A generic `request(method, params)` interface
+- Event-based state updates (`statusChanged`, `accountsChanged`, etc.)
+- A standardized, machine-readable error model
+
+The dApp API intentionally mirrors this structure so that wallets and dApps can interoperate using a minimal, predictable, and widely recognized interaction pattern. At the same time, it extends these semantics to accommodate Canton-specific features such as privacy-preserving participants, multi-party workflows, synchronized settlement, and multi-validator environments.
+
+The API can also be wrapped in a **Provider object**, just like the Ethereum provider model, ensuring a familiar integration pattern and smooth developer onboarding.
+
+### Transport-agnostic design
+
+Rather than binding dApps to a specific communication channel, the CIP defines the API using **OpenRPC**, allowing Wallet Providers to expose the interface over any transport, such as:
+- `postMessage` for browser extensions
+- HTTPS endpoints for remote custody services
+- WebSockets for persistent desktop clients
+- In-app bridges for mobile applications
+
+This transport-agnostic approach was selected to accommodate the wide variety of custody models in use within Canton deployments – from browser wallets to enterprise HSM-backed signing gateways – while ensuring that all remain interoperable with the same dApp code. Established providers such as WalletConnect are also compatible with this model.
+
+Alternative designs that use a single mandated transport (e.g., WebSockets or postMessage only) were considered but rejected because they would exclude significant wallet categories, particularly remote or server-side custody solutions.
+
+### Interoperability with the JSON Ledger API
+
+The dApp API does not replace the JSON Ledger API; instead, it **extends** it. The inclusion of the `ledgerApi` method allows dApps to utilize the existing ledger API without bypassing the Wallet Provider. This avoids duplicating APIs and preserves the Ledger API as the canonical source of truth for ledger semantics. The WebSocket endpoints defined in the Ledger API are not included within the scope of the `ledgerApi` method in this specification, as proxying WebSockets over JSON-RPC is technically too complex. Supporting them might be done as a future extension to the standard.
+
+### Direct versus proxied Ledger API access
+
+For dApp API providers that expose a **server-side** implementation of the API using the asynchronous specification, scalability concerns arise when proxying Ledger API read requests. While the Ledger API server is optimized for high-throughput, multi-client read access, wallet providers should not be expected to offer comparable performance when proxying such requests through an additional abstraction layer. Therefore, a dApp connected to such a server-side provider **MUST** perform read operations directly against the Ledger API, using the network access parameters (Ledger API endpoint and access token) when supplied by the provider.
+
+### Minimal but sufficient scope
+
+During design discussions, another alternative was to expose rich, multi-step transaction flows or high-level Canton workflow abstractions. These were rejected in favor of a **minimal, low-level operation set**:
+- Connect
+- Sign
+- Submit commands
+- Read from the ledger
+- Observe account and network changes
+
+This keeps Wallet Providers lightweight and avoids imposing application-level conventions that vary widely across Canton deployments.
+
+### Topology-related capabilities
+
+The dApp API does not currently expose topology-related capabilities, such as party allocation, directly to dApps. This decision was made to separate concerns and reduce the attack surface: topology operations typically require elevated privileges and administrative access that should not be exposed to standard dApps.
+
+Instead, these capabilities are delegated to the **Wallet Provider**, which has access to the administrative APIs (with the necessary permissions) and can perform such operations securely.
+
+This approach also aligns with the broader goal of keeping the dApp API forward-compatible and focused on ledger interaction, signing, and user-centric workflows, leaving provider-specific administrative tasks out of the standard interface.
+
+### Supporting Client-side and Remote Wallets
+
+The dApp API is split into synchronous and asynchronous variants to address the distinct operational constraints of different Wallet deployments. Client-side Wallets, such as browser extensions, can handle synchronous interactions because the user is directly available to approve actions in real time. Remote or server-side Wallets, in contrast, face transport limitations (e.g., HTTP request timeouts) and cannot block while waiting for user input. By introducing an asynchronous variant, the dApp API allows server-side Wallets to return a `userUrl` for required actions and emit events once the user completes them. This design preserves security guarantees, supports scalable back-end deployments, and ensures that dApps can interact uniformly with both client-side and remote Wallets without changing application logic.
+
+### Community consensus and objections
+
+Throughout discussions on cip-discuss, several concerns were raised and addressed:
+
+- **Risk of over-abstracting ledger semantics** → mitigated by exposing the existing Ledger API via `ledgerApi` instead of redefining it
+- **Fear that multiple transports would fragment the ecosystem** → resolved by defining a single canonical OpenRPC specification, transport-agnostic but semantically precise.
+- **Concerns about browser vs. enterprise wallets diverging** → addressed via the minimal operation set and remote API variant, enabling both models to conform to the same interface
+
+The resulting design reflects broad agreement among wallet providers, SDK authors, and dApp developers across the Canton ecosystem.
+
+## References
+
+The following resources provide normative specifications, reference implementations, and SDKs compatible with the dApp API. The specifications listed below will become **normative with the v1.0.0 release**, while the client and server packages serve as **reference implementations** to illustrate correct usage.
+
+### Specifications
+
+Normative definition of the synchronous and asynchronous dApp API
+
+- dApp API Specification (Synchronous): [OpenRPC JSON](https://github.com/hyperledger-labs/splice-wallet-kernel/blob/main/api-specs/openrpc-dapp-api.json)
+- dApp API Specification (Asynchronous): [OpenRPC JSON](https://github.com/hyperledger-labs/splice-wallet-kernel/blob/main/api-specs/openrpc-dapp-remote-api.json)
+
+### Reference Implementations
+
+- Provider: [NPM package](https://www.npmjs.com/package/@canton-network/core-splice-provider) | [GitHub source](https://github.com/hyperledger-labs/splice-wallet-kernel)
+- dApp API Client (Synchronous): [NPM package](https://www.npmjs.com/package/@canton-network/core-wallet-dapp-rpc-client) | [GitHub source](https://github.com/hyperledger-labs/splice-wallet-kernel)
+- dApp API Client (Remote / Async): [NPM package](https://www.npmjs.com/package/@canton-network/core-wallet-dapp-remote-rpc-client) | [GitHub source](https://github.com/hyperledger-labs/splice-wallet-kernel)
+- dApp API Server (Remote / Async): [NPM package](https://www.npmjs.com/package/@canton-network/wallet-gateway-remote) | [GitHub source](https://github.com/hyperledger-labs/splice-wallet-kernel)
+
+### SDKs compatible with the dApp API
+
+- Canton dApp SDK (Digital Asset) [NPM package](https://www.npmjs.com/package/@canton-network/dapp-sdk) | [GitHub source](https://github.com/hyperledger-labs/splice-wallet-kernel/tree/main/sdk/dapp-sdk)
+- Console Wallet dApp SDK (PixelPlex) [NPM package](https://www.npmjs.com/package/@console-wallet/dapp-sdk)
+
+
+## Change log
+
+* **2025-11-28**: Initial draft of the proposal.