> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect with Chipi

> Let any Starknet dApp connect to a Chipi hosted smart-account wallet — passkey, gasless, no extension, no WalletConnect. The Argent/Ready "Web Wallet" model.

`@chipi-stack/starknet-connector` is a [starknet-react](https://starknet-react.com) /
[get-starknet](https://github.com/starknet-io/get-starknet) connector. A dApp adds
**one line** and its users can connect with their Chipi wallet — a passkey
smart-account that signs **gasless** through the paymaster. No browser extension,
no WalletConnect; the same hosted-wallet model Argent/Ready's "Web Wallet" and
Cartridge Controller use.

<Note>
  This is how Starknet dApps actually connect — via the get-starknet / starknet-react
  connector interface, not WalletConnect (which is draft/unused on Starknet).
</Note>

## Install

```bash theme={null}
npm install @chipi-stack/starknet-connector
```

## Add the connector

```tsx theme={null}
import { StarknetConfig, publicProvider } from "@starknet-react/core";
import { mainnet } from "@starknet-react/chains";
import { ChipiConnector } from "@chipi-stack/starknet-connector";

const connectors = [
  new ChipiConnector(), // "Connect with Chipi"
  // ...argent(), braavos(), etc.
];

export function Providers({ children }) {
  return (
    <StarknetConfig chains={[mainnet]} provider={publicProvider()} connectors={connectors}>
      {children}
    </StarknetConfig>
  );
}
```

Your existing `useConnect` / `useAccount` flow now offers **Connect with Chipi**,
and `account.signMessage(...)` / `account.execute(...)` route to the user's Chipi
wallet — gasless, signed with their passkey.

## How it works

```
your dApp                          Chipi hosted wallet (wallet.chipipay.com)
─────────                          ──────────────────────────────────────────
ChipiConnector.connect()
  ├─ opens a popup ──────────────►  /connect  (the user's authenticated wallet)
  └─ postMessage  ◄────────────►    approval UI (passkey + gasless paymaster)
account.execute(calls)
  └─ wallet_addInvokeTransaction ─►  user approves ─► sponsored tx ─► tx hash
```

1. `ChipiConnector` is **transport only** — it opens the hosted wallet in a popup
   and forwards get-starknet `wallet_*` RPC calls over `postMessage`. It holds no
   keys and signs nothing itself.
2. The **hosted wallet** (`/connect`) authenticates the user, renders a **decoded
   approval** for every connect / sign / execute, then runs the real passkey +
   paymaster path and posts the result back.
3. `connector.account(provider)` wraps the channel in a `starknet.js`
   `WalletAccount`, so the dApp sees a standard `AccountInterface`.

## The approval & security model

The hosted wallet — not the dApp — owns approval, and it decodes what's being
signed so the user is never blind-signing:

* **Connect** shows the dApp's origin + the address being shared, and the user
  must approve (never automatic).
* **Execute** decodes calls against known tokens into human intent — *"Approve
  spending 10 USDC to 0x…"* with a loud **UNLIMITED** badge over the threshold,
  *"Send 5 USDC to 0x…"*, or an explicit *"Unrecognized contract"* warning (it
  never invents intent). Gas reads **"Free · covered by Chipi"**.
* **signTypedData** decodes the SNIP-12 message into labeled fields and
  highlights spend-authorization keys (spender / amount / deadline). Typed data
  it can't read is **hard-blocked** — the user can't blind-sign it. (Of 2024's
  \~\$494M in reported wallet-drainer losses, 56.7% of phishing thefts used
  blind-signed `Permit`-style typed data; this discipline closes that vector.)

## Try the example

A runnable starknet-react example lives in the repo:
[`examples/connect-with-chipi`](https://github.com/chipi-pay/sdks/tree/main/examples/connect-with-chipi).
It connects, signs typed data, and runs a gasless execute against a local Chipi
wallet — the full round-trip.

## Options

```ts theme={null}
new ChipiConnector({
  walletUrl: "https://wallet.chipipay.com", // hosted wallet base URL (default)
  id: "chipi",
  name: "Connect with Chipi",
  icon: "data:image/svg+xml;base64,...",
  register: true, // self-register on window for scanning dApps (default)
});
```

Instantiating the connector also **self-registers** the wallet on `window`
(`window.starknet_chipi` + `starknet:announceWallet`, the get-starknet /
Starknet-Wallet-Standard discovery path) so dApps that *scan* for wallets find
"Connect with Chipi" without importing this package — the same trick Cartridge
Controller uses. Pass `register: false` to opt out; it's a no-op during SSR.

## Compatibility & limits

* `@starknet-react/core` **>= 3** (peer) · `starknet` **>= 8.1.2** (peer).
* **Starknet mainnet** — pass a mainnet `provider`.
* **Popup-based** (external dApps). An in-app-browser ("parent") mode is in the
  transport but not yet exposed.
* One approval at a time; a dApp that fires two prompts truly simultaneously has
  its second request rejected (most dApps serialize).
