Skip to content

Commit

Permalink
Merge pull-request #351
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewkmin committed Oct 16, 2024
2 parents 705882d + 41d84d3 commit 9c41088
Show file tree
Hide file tree
Showing 62 changed files with 1,808 additions and 647 deletions.
3 changes: 1 addition & 2 deletions examples/deployer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@turnkey/api-key-stamper": "workspace:^",
"@turnkey/sdk-server": "workspace:*",
"@turnkey/ethers": "workspace:*",
"@turnkey/http": "workspace:*",
"dotenv": "^16.0.3",
"ethers": "^6.10.0",
"solc": "0.8.13"
Expand Down
83 changes: 0 additions & 83 deletions examples/deployer/src/createNewEthereumPrivateKey.ts

This file was deleted.

54 changes: 14 additions & 40 deletions examples/deployer/src/createNewWallet.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
import {
TurnkeyClient,
createActivityPoller,
TurnkeyActivityError,
} from "@turnkey/http";
import { ApiKeyStamper } from "@turnkey/api-key-stamper";
import { Turnkey as TurnkeySDKServer } from "@turnkey/sdk-server";
import * as crypto from "crypto";
import { refineNonNull } from "./util";

export async function createNewWallet() {
console.log("creating a new wallet on Turnkey...\n");
const turnkeyClient = new TurnkeySDKServer({
apiBaseUrl: "https://api.turnkey.com",
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
defaultOrganizationId: process.env.ORGANIZATION_ID!,
});

const walletName = `ETH Wallet ${crypto.randomBytes(2).toString("hex")}`;

try {
const turnkeyClient = new TurnkeyClient(
{ baseUrl: process.env.BASE_URL! },
new ApiKeyStamper({
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
})
);

const activityPoller = createActivityPoller({
client: turnkeyClient,
requestFn: turnkeyClient.createWallet,
});

const completedActivity = await activityPoller({
type: "ACTIVITY_TYPE_CREATE_WALLET",
timestampMs: String(Date.now()),
organizationId: process.env.ORGANIZATION_ID!,
parameters: {
const { walletId, addresses } = await turnkeyClient
.apiClient()
.createWallet({
walletName,
accounts: [
{
Expand All @@ -40,12 +25,9 @@ export async function createNewWallet() {
addressFormat: "ADDRESS_FORMAT_ETHEREUM",
},
],
},
});
});

const wallet = refineNonNull(completedActivity.result.createWalletResult);
const walletId = refineNonNull(wallet.walletId);
const address = refineNonNull(wallet.addresses[0]);
const address = refineNonNull(addresses[0]);

// Success!
console.log(
Expand All @@ -58,15 +40,7 @@ export async function createNewWallet() {
"Now you can take the address, put it in `.env.local` (`SIGN_WITH=<address>`), then re-run the script.",
].join("\n")
);
} catch (error) {
// If needed, you can read from `TurnkeyActivityError` to find out why the activity didn't succeed
if (error instanceof TurnkeyActivityError) {
throw error;
}

throw new TurnkeyActivityError({
message: "Failed to create a new Ethereum wallet",
cause: error as Error,
});
} catch (err: any) {
throw new Error("Failed to create a new Ethereum wallet: " + err);
}
}
20 changes: 8 additions & 12 deletions examples/deployer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });

import { TurnkeySigner } from "@turnkey/ethers";
import { ethers } from "ethers";
import { TurnkeyClient } from "@turnkey/http";
import { ApiKeyStamper } from "@turnkey/api-key-stamper";
import { Turnkey as TurnkeySDKServer } from "@turnkey/sdk-server";
import { createNewWallet } from "./createNewWallet";
import compile from "./compile";
import { print } from "./util";
Expand All @@ -19,19 +18,16 @@ async function main() {
return;
}

const turnkeyClient = new TurnkeyClient(
{
baseUrl: process.env.BASE_URL!,
},
new ApiKeyStamper({
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
})
);
const turnkeyClient = new TurnkeySDKServer({
apiBaseUrl: "https://api.turnkey.com",
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
defaultOrganizationId: process.env.ORGANIZATION_ID!,
});

// Initialize a Turnkey Signer
const turnkeySigner = new TurnkeySigner({
client: turnkeyClient,
client: turnkeyClient.apiClient(),
organizationId: process.env.ORGANIZATION_ID!,
signWith: process.env.SIGN_WITH!,
});
Expand Down
4 changes: 4 additions & 0 deletions examples/kitchen-sink/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
API_PUBLIC_KEY="<Turnkey API Public Key (that starts with 02 or 03)>"
API_PRIVATE_KEY="<Turnkey API Private Key>"
BASE_URL="https://api.turnkey.com"
ORGANIZATION_ID="<Turnkey organization ID>"
7 changes: 7 additions & 0 deletions examples/kitchen-sink/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Kitchen Sink

A playground and example bank for making Turnkey requests in various ways:

- `src/http`: create Turnkey requests in the most primitive way, using `@turnkey/http` and a stamper (e.g. `@turnkey/api-key-stamper`)
- `src/sdk-server`: create Turnkey requests using `@turnkey/sdk-server`, which abstracts away some of the internals in the above method
- 🚧 WIP `src/sdk-browser`: create Turnkey requests using `@turnkey/sdk-browser`, which also abstracts away some of the internals from the `@turnkey/http` approach. Note that `@turnkey/sdk-browser` has an interface identical to `@turnkey/sdk-server`
19 changes: 19 additions & 0 deletions examples/kitchen-sink/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@turnkey/kitchen-sink",
"version": "0.1.0",
"private": true,
"scripts": {
"start-sdk-server": "tsx sdkServerClient.ts",
"start-http": "tsx httpClient.ts",
"clean": "rimraf ./dist ./.cache",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@turnkey/http": "workspace:*",
"@turnkey/api-key-stamper": "workspace:*",
"@turnkey/sdk-server": "workspace:*",
"@turnkey/sdk-react": "workspace:*",
"@turnkey/sdk-browser": "workspace:*",
"dotenv": "^16.0.3"
}
}
68 changes: 68 additions & 0 deletions examples/kitchen-sink/src/http/createApiKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as path from "path";
import * as dotenv from "dotenv";

// Load environment variables from `.env.local`
dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });

import { TurnkeyClient, createActivityPoller } from "@turnkey/http";
import { ApiKeyStamper } from "@turnkey/api-key-stamper";
import { refineNonNull } from "../utils";

async function main() {
console.log("creating a new private key on Turnkey...\n");

const turnkeyClient = new TurnkeyClient(
{ baseUrl: process.env.BASE_URL! },
new ApiKeyStamper({
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
})
);

const activityPoller = createActivityPoller({
client: turnkeyClient,
requestFn: turnkeyClient.createApiKeys,
});

const userId = "<user id>";
const apiKeyName = "<API key name>";
const publicKey = "<API public key>";
const curveType = "API_KEY_CURVE_P256"; // this is the default

const activity = await activityPoller({
type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2",
organizationId: process.env.ORGANIZATION_ID!,
parameters: {
userId,
apiKeys: [
{
apiKeyName,
publicKey,
curveType,
},
],
},
timestampMs: String(Date.now()), // millisecond timestamp
});

const newApiKeyIds = refineNonNull(
activity.result.createApiKeysResult?.apiKeyIds
);

// Success!
console.log(
[
`New API key created!`,
`- ID: ${newApiKeyIds[0]}`,
`- Public Key: ${publicKey}`,
`- Name: ${apiKeyName}`,
`- User ID: ${userId}`,
``,
].join("\n")
);
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
69 changes: 69 additions & 0 deletions examples/kitchen-sink/src/http/createEthereumPrivateKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import * as path from "path";
import * as dotenv from "dotenv";

// Load environment variables from `.env.local`
dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });

import { TurnkeyClient } from "@turnkey/http";
import { createActivityPoller } from "@turnkey/http";
import { ApiKeyStamper } from "@turnkey/api-key-stamper";
import * as crypto from "crypto";
import { refineNonNull } from "../utils";

async function main() {
console.log("creating a new private key on Turnkey...\n");

const turnkeyClient = new TurnkeyClient(
{ baseUrl: process.env.BASE_URL! },
new ApiKeyStamper({
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
})
);

const activityPoller = createActivityPoller({
client: turnkeyClient,
requestFn: turnkeyClient.createPrivateKeys,
});

const privateKeyName = `ETH Key ${crypto.randomBytes(2).toString("hex")}`;

const activity = await activityPoller({
type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2",
organizationId: process.env.ORGANIZATION_ID!,
parameters: {
privateKeys: [
{
privateKeyName,
curve: "CURVE_SECP256K1",
addressFormats: ["ADDRESS_FORMAT_ETHEREUM"],
privateKeyTags: [],
},
],
},
timestampMs: String(Date.now()), // millisecond timestamp
});

const privateKeys = refineNonNull(
activity.result.createPrivateKeysResultV2?.privateKeys
);
const privateKeyId = refineNonNull(privateKeys?.[0]?.privateKeyId);
const address = refineNonNull(privateKeys?.[0]?.addresses?.[0]?.address);

// Success!
console.log(
[
`New Ethereum private key created!`,
`- Name: ${privateKeyName}`,
`- Private key ID: ${privateKeyId}`,
`- Address: ${address}`,
``,
"Now you can take the private key ID, put it in `.env.local`, then re-run the script.",
].join("\n")
);
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
Loading

0 comments on commit 9c41088

Please sign in to comment.