<VersionWarning version="0.1" />

# How to use a Turnkey signer with permissionless.js

[Turnkey](https://turnkey.com/) is a key infrastructure provider with a great developer API and a powerful security policy engine.

By combining permissionless.js with Turnkey, you can create **custodial AA wallets** whose security is provided by Turnkey, with powerful functionalities such as sponsoring gas, batching transactions, etc.

## Setup

To use Turnkey with permissionless.js, first create an application that integrates with Turnkey.

* Refer to the [Turnkey documentation site](https://docs.turnkey.com/) for instructions on setting up an application with the Turnkey.
* For a quick start, Turnkey provides examples, available [here](https://docs.turnkey.com/getting-started/examples).

## Integration

Integrating permissionless.js with Turnkey is straightforward after setting up the project. Turnkey provides an Externally Owned Account (EOA) wallet to use as a signer with permissionless.js accounts.

### Create the TurnkeyClient and a Turnkey viem account

After following the Turnkey documentation, you will have access to a `TurnkeyClient`. An example is shown below that you can use to create a `SmartAccountSigner` object:

```typescript
import { TurnkeyClient } from "@turnkey/http"
import { createAccount } from "@turnkey/viem"
import { walletClientToSmartAccountSigner } from "permissionless"
import { createWalletClient, http } from "viem"

// Param options here will be specific to your project.  See the Turnkey docs for more info.
const turnkeyClient = new TurnkeyClient({ baseUrl: "" }, stamper)

const turnkeyAccount = await createAccount({
	client: turnkeyClient,
	organizationId: subOrganizationId, // Your subOrganization id
	signWith: signWith, // Your suborganization `signWith` param.
})

// Create a SmartAccountSigner from the turnkeyAccount
const walletClient = createWalletClient({
	account: turnkeyAccount,
	transport: http("https://sepolia.rpc.thirdweb.com"),
})

const smartAccountSigner = walletClientToSmartAccountSigner(walletClient)
```

### Use with permissionless.js

:::code-group
```ts [SimpleAccount]
import { signerToSimpleSmartAccount } from "permissionless/accounts"
import {
	createPimlicoBundlerClient,
	createPimlicoPaymasterClient,
} from "permissionless/clients/pimlico"
import { createPublicClient, http } from "viem"
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
import { sepolia } from "viem/chains"

const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=<api-key>`

const pimlicoPaymaster = createPimlicoPaymasterClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const bundlerClient = createPimlicoBundlerClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const publicClient = createPublicClient({
	transport: http("https://sepolia.rpc.thirdweb.com"),
	chain: sepolia,
})

const smartAccount = await signerToSimpleSmartAccount(publicClient, {
	signer: smartAccountSigner,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const smartAccountClient = createSmartAccountClient({
	account: smartAccount,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
	chain: sepolia, // or whatever chain you are using
	bundlerTransport: http(pimlicoRpcUrl, {
		timeout: 30_000, // optional
	}),
	middleware: {
		gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast,
		sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation,
	},
})
```

```ts [Safe Account]
import { signerToSafeSmartAccount } from "permissionless/accounts"
import {
	createPimlicoBundlerClient,
	createPimlicoPaymasterClient,
} from "permissionless/clients/pimlico"
import { createPublicClient, http } from "viem"
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
import { sepolia } from "viem/chains"

const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=<api-key>`

const pimlicoPaymaster = createPimlicoPaymasterClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const bundlerClient = createPimlicoBundlerClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const publicClient = createPublicClient({
	transport: http("https://sepolia.rpc.thirdweb.com"),
	chain: sepolia,
})

const smartAccount = await signerToSafeSmartAccount(publicClient, {
	signer: smartAccountSigner,
	safeVersion: "1.4.1",
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const smartAccountClient = createSmartAccountClient({
	account: smartAccount,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
	chain: sepolia, // or whatever chain you are using
	bundlerTransport: http(pimlicoRpcUrl, {
		timeout: 30_000, // optional
	}),
	middleware: {
		gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast,
		sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation,
	},
})
```

```ts [Kernel Account]
import { signerToEcdsaKernelSmartAccount } from "permissionless/accounts"
import {
	createPimlicoBundlerClient,
	createPimlicoPaymasterClient,
} from "permissionless/clients/pimlico"
import { createPublicClient, http } from "viem"
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
import { sepolia } from "viem/chains"

const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=<api-key>`

const pimlicoPaymaster = createPimlicoPaymasterClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const bundlerClient = createPimlicoBundlerClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const publicClient = createPublicClient({
	transport: http("https://sepolia.rpc.thirdweb.com"),
	chain: sepolia,
})

const smartAccount = await signerToEcdsaKernelSmartAccount(publicClient, {
	signer: smartAccountSigner,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const smartAccountClient = createSmartAccountClient({
	account: smartAccount,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
	chain: sepolia, // or whatever chain you are using
	bundlerTransport: http(pimlicoRpcUrl, {
		timeout: 30_000, // optional
	}),
	middleware: {
		gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast,
		sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation,
	},
})
```

```ts [Biconomy Account]
import { signerToBiconomySmartAccount } from "permissionless/accounts"
import {
	createPimlicoBundlerClient,
	createPimlicoPaymasterClient,
} from "permissionless/clients/pimlico"
import { createPublicClient, http } from "viem"
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
import { sepolia } from "viem/chains"

const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=<api-key>`

const pimlicoPaymaster = createPimlicoPaymasterClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const bundlerClient = createPimlicoBundlerClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const publicClient = createPublicClient({
	transport: http("https://sepolia.rpc.thirdweb.com"),
	chain: sepolia,
})

const smartAccount = await signerToBiconomySmartAccount(publicClient, {
	signer: smartAccountSigner,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const smartAccountClient = createSmartAccountClient({
	account: smartAccount,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
	chain: sepolia, // or whatever chain you are using
	bundlerTransport: http(pimlicoRpcUrl, {
		timeout: 30_000, // optional
	}),
	middleware: {
		gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast,
		sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation,
	},
})
```

```ts [TrustWallet Account]
import { signerToTrustSmartAccount } from "permissionless/accounts"
import {
	createPimlicoBundlerClient,
	createPimlicoPaymasterClient,
} from "permissionless/clients/pimlico"
import { createPublicClient, http } from "viem"
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
import { sepolia } from "viem/chains"

const pimlicoRpcUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=<api-key>`

const pimlicoPaymaster = createPimlicoPaymasterClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const bundlerClient = createPimlicoBundlerClient({
	transport: http(pimlicoRpcUrl),
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const publicClient = createPublicClient({
	transport: http("https://sepolia.rpc.thirdweb.com"),
	chain: sepolia,
})

const smartAccount = await signerToTrustSmartAccount(publicClient, {
	signer: smartAccountSigner,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
})

const smartAccountClient = createSmartAccountClient({
	account: smartAccount,
	entryPoint: ENTRYPOINT_ADDRESS_V06,
	chain: sepolia, // or whatever chain you are using
	bundlerTransport: http(pimlicoRpcUrl, {
		timeout: 30_000, // optional
	}),
	middleware: {
		gasPrice: async () => (await bundlerClient.getUserOperationGasPrice()).fast,
		sponsorUserOperation: pimlicoPaymaster.sponsorUserOperation,
	},
})
```
:::
