Skip to content

Commit

Permalink
update with wallets
Browse files Browse the repository at this point in the history
  • Loading branch information
timurnkey committed Nov 3, 2023
1 parent 281faaf commit d79d2dc
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 264 deletions.
298 changes: 111 additions & 187 deletions api/public_api.swagger.json

Large diffs are not rendered by default.

40 changes: 21 additions & 19 deletions docs/getting-started/Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,27 @@ Turnkey infrastructure is flexible by default. We intentionally prioritize low-l

That said, we have built out several example services and applications to help illustrate the types of functionality that Turnkey can enable.

## SDK code examples

Clone or fork the Turnkey SDK repo [here](https://github.com/tkhq/sdk) to explore a few “turnkey” examples:

| Example | Description |
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [`deployer`](https://github.com/tkhq/sdk/tree/main/examples/deployer/) | Compile and deploy a smart contract |
| [`rebalancer`](https://github.com/tkhq/sdk/tree/main/examples/rebalancer) | A demo application which showcases an example of how to use Turnkey for managing multiple types of keys & users |
| [`sweeper`](https://github.com/tkhq/sdk/tree/main/examples/sweeper/) | Sweep funds from one address to a different address |
| [`trading-runner`](https://github.com/tkhq/sdk/tree/main/examples/trading-runner) | A sample application demonstrating a trading operation, using various private keys, users, and policies, powered by Uniswap. |
| [`with-ethers`](https://github.com/tkhq/sdk/tree/main/examples/with-ethers/) | Create a new Ethereum address, then sign and broadcast a transaction using the Ethers signer with Infura |
| [`with-viem`](https://github.com/tkhq/sdk/tree/main/examples/with-viem/) | Sign and broadcast a transaction using the Turnkey Custom Account and Infura |
| [`with-cosmjs`](https://github.com/tkhq/sdk/tree/main/examples/with-cosmjs/) | Create a new Cosmos address, then sign and broadcast a transaction on Celestia testnet using the CosmJS signer |
| [`with-solana`](https://github.com/tkhq/sdk/tree/main/examples/with-solana/) | Create a new Solana address, then sign and broadcast a transaction on Solana's devnet |
| [`with-gnosis`](https://github.com/tkhq/sdk/tree/main/examples/with-gnosis/) | Create new Ethereum addresses, configure a 3/3 Gnosis safe, and create + execute a transaction from it |
| [`with-uniswap`](https://github.com/tkhq/sdk/tree/main/examples/with-uniswap/) | Sign and broadcast a Uniswap v3 trade using the Ethers signer with Infura |
| [`with-nonce-manager`](https://github.com/tkhq/sdk/tree/main/examples/with-nonce-manager/) | Create a new Ethereum address, then sign and broadcast multiple transactions in a sequential or optimistic manner. |
| [`with-offline`](https://github.com/tkhq/sdk/tree/main/examples/with-offline/) | Sign a Turnkey request in offline context |
| [`with-federated-passkeys`](https://github.com/tkhq/sdk/tree/main/examples/with-federated-passkeys/) | A NextJS app that demonstrates how to use Turnkey to build a federated, webauthn powered authentication flow |
## Code Examples

| Example | Description |
| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [`demo-consumer-wallet`](https://github.com/tkhq/demo-consumer-wallet) | A minimal consumer wallet app powered by Turnkey and WalletConnect |
| [`demo-passkey-wallet`](https://github.com/tkhq/demo-passkey-wallet) | A minimal consumer wallet app powered by Turnkey and passkeys |
| [`demo-ethers-passkeys`](https://github.com/tkhq/demo-ethers-passkeys) | A NextJS app that demonstrates how to use `@turnkey/ethers` to build a passkey-powered application |
| [`demo-viem-passkeys`](https://github.com/tkhq/demo-viem-passkeys) | A NextJS app that demonstrates how to use `@turnkey/viem` to build a passkey-powered application |
| [`deployer`](/examples/deployer/) | Compile and deploy a smart contract |
| [`rebalancer`](/examples/rebalancer/) | A demo application which showcases an example of how to use Turnkey for managing multiple types of keys & users |
| [`sweeper`](/examples/sweeper/) | Sweep funds from one address to a different address |
| [`trading-runner`](/examples/trading-runner/) | A sample application demonstrating a trading operation, using various private keys, users, and policies, powered by Uniswap |
| [`with-ethers`](/examples/with-ethers/) | Create a new Ethereum address, then sign and broadcast a transaction using the Ethers signer with Infura |
| [`with-viem`](/examples/with-viem/) | Sign and broadcast a transaction using the Turnkey Custom Account and Infura |
| [`with-cosmjs`](/examples/with-cosmjs/) | Create a new Cosmos address, then sign and broadcast a transaction on Celestia testnet using the CosmJS signer |
| [`with-solana`](/examples/with-solana/) | Create a new Solana address, then sign and broadcast a transaction on Solana's devnet |
| [`with-gnosis`](/examples/with-gnosis/) | Create new Ethereum addresses, configure a 3/3 Gnosis safe, and create + execute a transaction from it |
| [`with-uniswap`](/examples/with-uniswap/) | Sign and broadcast a Uniswap v3 trade using the Ethers signer with Infura |
| [`with-nonce-manager`](/examples/with-nonce-manager/) | Create a new Ethereum address, then sign and broadcast multiple transactions in a sequential or optimistic manner |
| [`with-offline`](/examples/with-offline/) | Sign a Turnkey request in offline context |
| [`with-federated-passkeys`](/examples/with-federated-passkeys/) | A NextJS app that demonstrates how to use Turnkey to build a federated, webauthn powered authentication flow |

## Demos built with Turnkey

Expand Down
84 changes: 39 additions & 45 deletions docs/getting-started/Quickstart.md
Original file line number Diff line number Diff line change
@@ -1,108 +1,102 @@
---
id: quickstart
sidebar_position: 2
description: Get onboarded and sign your first ETH transaction
slug: /getting-started/quickstart
description: Onboard and sign your first Ethereum transaction
slug: /getting-started/quickstart
---
# Quickstart
# Quickstart

This quickstart will guide you through Turnkey’s onboarding, API key generation, and ETH signing via Turnkey’s CLI.
This quickstart will guide you through Turnkey’s onboarding, adding an API key, creating a wallet, and signing your first Ethereum transaction.

## Create your Turnkey Organization

- Visit [app.turnkey.com/dashboard/auth/initial](https://app.turnkey.com/dashboard/auth/initial) and enter your email address.
- Visit [app.turnkey.com/dashboard/auth/initial](https://app.turnkey.com/dashboard/auth/initial) and enter your email address
- Confirm your email by clicking on the link inside of the confirmation email
- Click "Continue" and choose your first authenticator (laptop biometrics or security key)
- Pick a name for your organization click "Continue"
- Log in by clicking the "Log in" button

Once your log in is successful, you will land on the dashboard screen. You'll initially be on the Activities tab, and can explore the Users, Private Keys, and Policies tabs.
- Follow the prompts to add your first authenticator and create your organization

## Find your Organization ID

All public API endpoints need an organization ID. You can copy your organization ID by clicking on the user dropdown in the top right corner of the app as shown in the image below.
All API requests require an organization ID. Yours can be located in the user dropdown menu at the top right corner of the dashboard.

![](https://files.readme.io/d8ff903-Screen_Shot_2022-12-12_at_2.15.04_PM.png "Screen Shot 2022-12-12 at 2.15.04 PM.png")
<img src="/img/quickstart/find_organization_id.png" alt="Find organization ID" width="940px" />

For convenience, it's worth setting this as a permanent shell variable:

```sh
export ORGANIZATION_ID="<Your Org ID>"
```

## Create a new API Key
## Add an API key

Turnkey API Keys are generic public / private key pairs. To generate a new key, use our CLI.
Turnkey API Keys are generic public / private key pairs that allow you to make requests to our API. To generate a new key pair, we'll use the Turnkey CLI.

#### Installing Turnkey's CLI, `turnkey`
#### Installing `turnkey`

```sh
brew install tkhq/tap/turnkey
```

Note: We are employing [Homebrew](https://brew.sh/) in this guide as a quick and easy install path. For an installation path that requires no trust in external parties, refer to our [tkcli repo](https://github.com/tkhq/tkcli).

#### Generate a new API key

In your Turnkey implementation, an API key authenticates all API requests.
We are employing [Homebrew](https://brew.sh/) in this guide as a quick and easy install path. For an installation path that **requires no trust in external parties**, refer to our [CLI repo](https://github.com/tkhq/tkcli).

When you run this command, Turnkey’s CLI generates a standard API key pair and **stores the API private key locally**. If you've run this command once already, add `-k keyname` to the end of the command below, replacing "keyname" with any name you'd like. Otherwise, run the command as written to use our default naming.
#### Generate an API key

```sh
turnkey gen --organization $ORGANIZATION_ID --key-name quickstart
turnkey generate-api-key --organization $ORGANIZATION_ID --key-name quickstart
```

Copy the `publicKey` field in the output.
When you run this command, Turnkey’s CLI generates an API key pair and **stores the API private key locally**. Copy the `publicKey` field in the output. In the next step, we'll add this to our User.

## Add your public API Key
#### Add your public API key

Head to the "Users" tab and click on the Root User:
Navigate to your user page by clicking on "User Details" in the user dropdown menu.

![](https://files.readme.io/d8fbe2b-Screen_Shot_2022-12-12_at_12.32.58_PM_2.png "Screen Shot 2022-12-12 at 12.32.58 PM_2.png")
<img src="/img/quickstart/find_user_details.png" alt="Find user details" width="940px" />

Click on "Add new API keys" and enter a label for the public key you want to add. After this succeeds, you should be all set to interact with our Public API.
Click on "Create API keys" and follow the prompts to add the generarated public API key. You'll be required to authenticate with the same authenticator used during onboarding. After this succeeds, you should be all set to interact with our API.

## Create a new Ethereum Private Key
## Create a Wallet

Creating a new key is done with the `/private_keys` endpoint. We call this with the Turnkey CLI, which abstracts away API routes and signatures:
Wallets are collections of cryptographic key pairs typically used for sending and receiving digital assets. To create one, we need to provide a name:

```
turnkey private-keys create --name "ETH Key" --address-format ADDRESS_FORMAT_ETHEREUM --curve CURVE_SECP256K1 -k quickstart
turnkey wallets create --name default
```

Once the activity transitions to COMPLETE, visit the "Private Keys" tab in your dashboard and take note of the Key ID (e.g. `e624996e-11c4-48fb-ad56-874ff5a84615`), this is what we'll use to sign.
## Create an Ethereum account

![](https://files.readme.io/2812d13-Screen_Shot_2022-12-15_at_6.34.55_PM.png "Screen Shot 2022-12-15 at 6.34.55 PM.png")
To create a cryptographic key pair on our new Wallet, we need to pass our desired address format:

```
turnkey wallets accounts create --wallet default --address-format ADDRESS_FORMAT_ETHEREUM
```

Let's set it as a variable so we can use it to easily sign a transaction in the next step.
This command will produce an Ethereum address (e.g. `0x08cb1216C95149DF66978b574E484869512CE2bF`) that we'll need to sign a transaction. You can see your new Wallet account with:

```sh
export KEY_ID="<Your Key ID>"
```
turnkey wallets accounts list --wallet default
```

## Sign a Transaction

Now you can sign any Ethereum transaction you like with this new key with our [`sign_transaction` endpoint](https://docs.turnkey.com/api#tag/Signers/operation/SignTransaction). Make sure to replace the `unsignedTransaction` below with your own. You can use our [simple transaction generator](https://build.tx.xyz) if you need a quick transaction for testing:
Now you can sign an Ethereum transaction with this new address with our [`sign_transaction` endpoint](https://docs.turnkey.com/api#tag/Signers/operation/SignTransaction). Make sure to replace the `unsignedTransaction` below with your own. You can use our [simple transaction generator](https://build.tx.xyz) if you need a quick transaction for testing:

```sh
turnkey request --host api.turnkey.com --path /public/v1/submit/sign_transaction --body '{
turnkey request --path /public/v1/submit/sign_transaction --body '{
"timestampMs": "'"$(date +%s)"'000",
"type": "ACTIVITY_TYPE_SIGN_TRANSACTION",
"type": "ACTIVITY_TYPE_SIGN_TRANSACTION_V2",
"organizationId": "'"$ORGANIZATION_ID"'",
"parameters": {
"privateKeyId": "'"$KEY_ID"'",
"type": "TRANSACTION_TYPE_ETHEREUM",
"signWith": "<Your Ethereum address>",
"unsignedTransaction": "<Your Transaction>"
}
}' -k quickstart
```

The activity immediately comes back as "COMPLETED" because Turnkey's signer works synchronously. We do not need to change any Organization data. You can find the signature in the output of the command, or by visiting the activity details page for the signature activity.

If you'd like to broadcast your transaction, you can easily do so via [Etherscan](https://etherscan.io/pushTx).

## Sign a Transaction with `Ethers.js`

Turnkey provides an `Ethers` signer via the [`@turnkey/ethers`](https://www.npmjs.com/package/@turnkey/ethers) package on npm. You can use the signer to sign transactions, and bring your own provider to broadcast them.
## Next Steps

Check out the example on GitHub where we create a new Ethereum address, then sign and broadcast a transaction using the Turnkey signer: <https://github.com/tkhq/sdk/tree/main/examples/with-ethers/>
- Check out our [examples](/getting-started/examples) to see what can be built
- Learn more about [Organizations](/getting-started/organizations) and [Wallets](/getting-started/wallets)
- See our [API design](/api-introduction) or dive into our [API reference](/api)
57 changes: 57 additions & 0 deletions docs/getting-started/Wallets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
sidebar_position: 6
description: Learn about Wallets on Turnkey
slug: /getting-started/wallets
---
# Wallets

A hierarchical deterministic (HD) Wallet is a collection of cryptographic private/public key pairs that share a common seed. Wallets offer several advantages over raw private keys:
- They can be used across various cryptographic curves
- They can generate millions of addresses for various digital assets
- They can be represented by a checksummed, mnemonic phrase making them easier to backup and recover

```json
{
"walletId": "eb98ae4c-07eb-4117-9b2d-8a453c0e1e64",
"walletName": "default"
}
```

## Accounts

An account contains the directions for deriving a cryptographic key pair and correspoding address from a Wallet. In practice, this looks like:
- The Wallet seed and Account curve are used to create a root key pair
- The Account path format and path are used to derive an extended key pair from the root key pair
- The Account address format is used to derive the address from the extended public key

```json
{
"address": "0x7aAE6F67798D1Ea0b8bFB5b64231B2f12049DB5e",
"addressFormat": "ADDRESS_FORMAT_ETHEREUM",
"curve": "CURVE_SECP256K1",
"path": "m/44'/60'/0'/0/0",
"pathFormat": "PATH_FORMAT_BIP32",
"walletId": "eb98ae4c-07eb-4117-9b2d-8a453c0e1e64"
}
```

The account address is used to sign with the underlying extended private key.

#### Configuration

Certain address formats can only be used with particular curves. See the table below:

| Type | Address Format | Curve | Path Format | Path |
| -------------- | ---------------------------- | --------------- | ----------------- | ----------------- |
| **Public Key** | ADDRESS_FORMAT_COMPRESSED | all | PATH_FORMAT_BIP32 | |
| | ADDRESS_FORMAT_UNCOMPRESSED | CURVE_SECP256K1 | PATH_FORMAT_BIP32 | |
| **Ethereum** | ADDRESS_FORMAT_ETHEREUM | CURVE_SECP256K1 | PATH_FORMAT_BIP32 | m/44'/60'/0'/0/0 |
| **Cosmos** | ADDRESS_FORMAT_COSMOS | CURVE_SECP256K1 | PATH_FORMAT_BIP32 | m/44'/118'/0'/0/0 |
| **Solana** | ADDRESS_FORMAT_SOLANA | CURVE_ED25519 | PATH_FORMAT_BIP32 | m/44'/501'/0'/0' |

#### What if I don't see the address format for my network?
You can use `ADDRESS_FORMAT_COMPRESSED` to generate a public key which can be used to sign with.

#### What if I don't see the curve for my network?
Contact us!

17 changes: 14 additions & 3 deletions docs/policy-management/Policy-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ slug: /managing-policies/examples

## Access control

#### Allow a specific user to create private keys
#### Allow a specific user to create wallets

```json JSON
{
"policyName": "Allow user <USER_ID> to create private keys",
"policyName": "Allow user <USER_ID> to create wallets",
"effect": "EFFECT_ALLOW",
"consensus": "approvers.any(user, user.id == '<USER_ID>')",
"condition": "activity.resource == 'PRIVATE_KEY' && activity.action == 'CREATE'"
"condition": "activity.resource == 'WALLET' && activity.action == 'CREATE'"
}
```

Expand Down Expand Up @@ -52,6 +52,17 @@ slug: /managing-policies/examples

## Signing control

#### Allow a specific user to sign transactions with a specific wallet

```json
{
"policyName": "Allow <USER_ID> to sign transactions with <WALLET_ID>",
"effect": "EFFECT_ALLOW",
"consensus": "approvers.any(user, user.id == '<USER_ID>')",
"condition": "wallet.id == '<PRIVATE_KEY_ID>'"
}
```

#### Allow a specific user to sign transactions with a specific private key

```json
Expand Down
1 change: 0 additions & 1 deletion docs/policy-management/Policy-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ Our policies are defined using **JSON**. The `effect` determines if an activity

```json JSON
{
"policyName": "Allowlist for one user",
"effect": "EFFECT_ALLOW",
"consensus": "approvers.any(user, user.id == '4b894565-fa11-42fc-b813-5bf4ea3d53f9')",
"condition": "eth.tx.to == '<ALLOWED_ADDRESS>'"
Expand Down
Loading

0 comments on commit d79d2dc

Please sign in to comment.