For the complete documentation index, see llms.txt. This page is also available as Markdown.

Turnkey Integration (coming soon)

How to open and close leveraged positions from a Turnkey embedded wallet by bridging Turnkey's signer into wagmi with a small custom connector.

Turnkey provisions embedded wallets from an email-OTP, passkey, or OAuth login via its Auth Proxy (no backend required). A Turnkey embedded wallet is an ordinary EOA, so once you can sign with it, the on-chain path is the standard Direct EOA flow — approve / createPosition / requestClose over viem.

The one difference from Privy: Turnkey ships no wagmi connector, so if your app is built on wagmi you bridge Turnkey's signer in with a small custom connector. That bridge is the only Turnkey-specific code; nothing in the contract layer changes.

For the core lifecycle, ABIs, and the Direct EOA snippets, see On-Chain Integration.


1. Install and wrap your app

npm install @turnkey/react-wallet-kit @turnkey/viem
import {TurnkeyProvider} from "@turnkey/react-wallet-kit";
import "@turnkey/react-wallet-kit/styles.css";

export function Providers({children}: {children: React.ReactNode}) {
  return (
    <TurnkeyProvider
      config={{
        organizationId: import.meta.env.VITE_TURNKEY_ORG_ID,
        authProxyConfigId: import.meta.env.VITE_TURNKEY_AUTH_PROXY_CONFIG_ID,
      }}
    >
      {children}
    </TurnkeyProvider>
  );
}

Both ids come from the Turnkey dashboard: your organization ID and the WalletKit / Auth Proxy config ID (enable Auth Proxy and pick your auth methods first). Both are public client identifiers.


2. Log in and derive a viem account

useTurnkey() exposes the login trigger, the authenticated client, and the user's wallets. Each wallet account carries its own (sub-)organizationId — that's what createAccount must sign under.

handleLogin() from useTurnkey() opens the login modal.


3a. Open and close — plain viem (no wagmi)

If you are not on wagmi, use the Turnkey account directly with a viem walletClient. This is the simplest path.


3b. Open and close — bridging into wagmi

If your app already uses wagmi (so useWriteContract, useAccount, etc. just work), wrap the Turnkey account in an EIP-1193 provider and expose it through a custom wagmi connector. Delegate signing/sending to a viem walletClient and let reads fall through to the RPC:

Wrap it in a wagmi connector with createConnector, reading the live account from a module-level holder you populate on login (the signer only exists after the user authenticates). Then keep wagmi in sync with the Turnkey session: on login, build the account, set the holder, and call wagmi connect; on logout, clear it and disconnect. With that in place, the existing createPosition / requestClose wagmi calls run unchanged.

The official demo UI implements exactly this — see dimes-demo-ui (src/turnkey/provider.ts, src/turnkey/connector.ts, and the TurnkeyBridge in src/WalletProviders.tsx).


Funding the embedded wallet

handleOnRamp() from useTurnkey() opens the funding flow; or send pUSD and a little POL to the wallet directly. The vault pulls total_user_amount_usdc_units of pUSD; the wallet needs POL for gas.


Notes

  • wallet_address. Pass the Turnkey wallet's Ethereum address — the one that signs on-chain — as wallet_address to POST /prediction-markets/quotes.

  • Sub-organizations. Each end user gets a Turnkey sub-org; sign under the account's own organizationId, not the parent org id.

  • Export. handleExportWallet({walletId}) lets a user self-custody.

Last updated