Skip to content

Commit

Permalink
✨ create turnkey user account
Browse files Browse the repository at this point in the history
  • Loading branch information
cruzdanilo committed Nov 14, 2023
1 parent 52a61e7 commit a64991a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 14 deletions.
78 changes: 65 additions & 13 deletions app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { ApiKeyStamper } from "@turnkey/api-key-stamper";
import { TurnkeyClient, createActivityPoller, getWebAuthnAttestation } from "@turnkey/http";
import { encode } from "base64-arraybuffer";
import React, { useCallback } from "react";
import { Button, Platform } from "react-native";
import { getDeviceName } from "react-native-device-info";
import * as Sentry from "sentry-expo";
import { Text, XStack, YStack } from "tamagui";
import { useBlockNumber } from "wagmi";
Expand All @@ -11,19 +15,50 @@ export default function Home() {

const create = useCallback(() => {
const challenge = generateRandomBuffer();
const username = `exactly, ${new Date().toISOString().slice(0, 10)}`;
navigator.credentials
.create({
publicKey: {
rp: { id: rpId, name: "exactly" },
user: { id: challenge, name: username, displayName: username },
pubKeyCredParams: [{ alg: -7, type: "public-key" }],
authenticatorSelection: { requireResidentKey: true, residentKey: "required", userVerification: "required" },
challenge,
},
})
.then((credential) => {
console.log("credential", credential); // eslint-disable-line no-console
getWebAuthnAttestation({
publicKey: {
rp: { id: rpId, name: "exactly" },
user: { id: challenge, name: "exactly account", displayName: "exactly account" },
pubKeyCredParams: [{ alg: -7, type: "public-key" }],
authenticatorSelection: { requireResidentKey: true, residentKey: "required", userVerification: "required" },
challenge,
},
})
.then(async (attestation) => {
console.log("attestation", attestation); // eslint-disable-line no-console
if (!process.env.EXPO_PUBLIC_TURNKEY_ORGANIZATION_ID) throw new Error("missing turnkey organization id");
const client = turnkeyClient();
const activityPoller = createActivityPoller({ client, requestFn: client.createSubOrganization });
const completedActivity = await activityPoller({
type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4",
timestampMs: String(Date.now()),
organizationId: process.env.EXPO_PUBLIC_TURNKEY_ORGANIZATION_ID,
parameters: {
subOrganizationName: attestation.credentialId,
rootQuorumThreshold: 1,
rootUsers: [
{
apiKeys: [],
userName: "account",
authenticators: [
{ authenticatorName: await getDeviceName(), challenge: base64URLEncode(challenge), attestation },
],
},
],
wallet: {
walletName: "default",
accounts: [
{
curve: "CURVE_SECP256K1",
addressFormat: "ADDRESS_FORMAT_ETHEREUM",
pathFormat: "PATH_FORMAT_BIP32",
path: "m/44'/60'/0'/0/0",
},
],
},
},
});
console.log(completedActivity); // eslint-disable-line no-console
})
.catch(handleError);
}, []);
Expand All @@ -48,6 +83,10 @@ export default function Home() {
);
}

function base64URLEncode(buffer: ArrayBufferLike) {
return encode(buffer).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
}

function generateRandomBuffer() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
Expand All @@ -58,3 +97,16 @@ function handleError(error: unknown) {
console.log(error); // eslint-disable-line no-console
(Sentry.Native ?? Sentry.React).captureException(error); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
}

function turnkeyClient() {
if (!process.env.EXPO_PUBLIC_TURNKEY_API_PUBLIC_KEY || !process.env.EXPO_PUBLIC_TURNKEY_API_PRIVATE_KEY) {
throw new Error("missing turnkey api keys");
}
return new TurnkeyClient(
{ baseUrl: "https://api.turnkey.com" },
new ApiKeyStamper({
apiPublicKey: process.env.EXPO_PUBLIC_TURNKEY_API_PUBLIC_KEY,
apiPrivateKey: process.env.EXPO_PUBLIC_TURNKEY_API_PRIVATE_KEY,
}),
);
}
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
"@expo/vector-icons": "^13.0.0",
"@sentry/react-native": "^5.13.0",
"@tamagui/config": "^1.76.0",
"@turnkey/api-key-stamper": "^0.1.1",
"@turnkey/http": "^2.2.0",
"@turnkey/viem": "^0.3.2",
"@turnkey/webauthn-stamper": "^0.3.0",
"base64-arraybuffer": "^1.0.2",
"expo": "^49.0.18",
"expo-application": "~5.3.0",
Expand All @@ -44,6 +44,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native": "0.72.6",
"react-native-device-info": "^10.11.0",
"react-native-gesture-handler": "~2.12.0",
"react-native-get-random-values": "^1.9.0",
"react-native-safe-area-context": "4.6.3",
Expand Down

0 comments on commit a64991a

Please sign in to comment.