Skip to main content
Connect with Chipi has two halves. The connector runs in the dApp’s page and holds no keys. The wallet (the hosted wallet at wallet.chipipay.com, or your own host built on createChipiWindowObject / useChipiWalletObject) owns every approval and every signature.

What the SDK enforces

These hold for any wallet built on @chipi-stack/nextjs / @chipi-stack/chipi-react (14.16.0+):
  • Deny by default. The wallet object asks requestApproval for three things: connect, execute and signTypedData. Without a requestApproval callback, all three are refused (113) and a single console.warn says why. Nothing is ever auto-approved.
  • Connect is explicit. wallet_requestAccounts asks for a connect approval once per wallet object, even when the wallet is unlocked. silent_mode and wallet_getPermissions reveal nothing until then.
  • Typed data must be for this chain. wallet_signTypedData refuses a SNIP-12 domain with no chainId, or one that differs from the wallet’s (SN_MAIN and its hex form are the same chain), with 114 and without prompting. Bramble applies the same rule. (A missing chainId is refused from 14.17.0; 14.16.x let it through.)
  • No dApp can create a session. No wallet_* method creates a session or asks for a session approval. Sessions come only from the host calling createSession(policy) on useChipiWalletObject. With spendCaps, the session and its spending policies are registered in the same owner-signed transaction (sdk.sessions.setupSession). A cap that would mean “unlimited” on-chain (maxPerWindow = 0) is refused. The on-chain whitelist is per entrypoint selector, not per contract, so caps are what bound token spend.
The connector side (@chipi-stack/starknet-connector) ignores any message that doesn’t come from the wallet window it opened (0.4.0+), times out requests that get no answer, never reopens a closed wallet window outside a click, and (0.5.0+) answers passive calls such as wallet_getPermissions itself while no wallet window is open, so a page-load wallet scan never tries to open Chipi.

Error codes of the Chipi wallet object

createChipiWindowObject rejects with an Error whose numeric code follows the Starknet wallet API: Errors thrown by the host’s executeCalls or signTypedData reach the dApp as thrown. Through the connector, these codes arrive as err.code (see Errors).

What the hosted wallet adds

The hosted wallet at wallet.chipipay.com puts a review screen in front of each approval: the dApp’s origin and the address being shared on connect, decoded token intent on execute (amounts, recipients, an UNLIMITED badge on large approvals, a warning on unrecognized contracts), and labeled SNIP-12 fields on signTypedData. That screen lives in the hosted wallet, not in this SDK; if you build your own host, requestApproval is where you render it.

Message origins: a rule for wallet hosts

Every request the connector sends carries an origin field, but the dApp writes that field itself. A wallet host must identify the dApp by the browser-provided MessageEvent.origin of the message it received, and show and enforce that value. Never trust the origin inside the message: a phishing page can put any origin it likes there.

Where the trust boundary sits

ChipiConnector (running inside the dApp’s page) holds no keys and signs nothing: it only forwards wallet_* calls over postMessage to the hosted wallet, a separate origin the dApp never controls. The same is true of the browser extension: it injects the provider so dApps can discover Chipi, but every signature still happens on the hosted wallet’s own origin, behind the user’s passkey. Neither surface can exfiltrate a key that was never present. Other wallets on the same page, such as Bramble, are separate objects (window.starknet_bramble) with their own approvals. The Chipi connector never reads or calls them.
✅ Verified against the SDK source on 2026-10-12.