Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CreateSubOrgV3 #107

Merged
merged 3 commits into from
Sep 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
update federated passkeys demo
  • Loading branch information
andrewkmin committed Sep 2, 2023
commit eb2d64011114324c6833855c22bfed47f6eaca95
2 changes: 1 addition & 1 deletion examples/with-federated-passkeys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Now open `.env.local` and add the missing environment variables:

- `API_PUBLIC_KEY`
- `API_PRIVATE_KEY`
- `ORGANIZATION_ID`
- `NEXT_PUBLIC_ORGANIZATION_ID`
- `NEXT_PUBLIC_BASE_URL` (the `NEXT_PUBLIC` prefix makes the env variable accessible to the frontend app)

### 3/ Running the app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type CreateSubOrgRequest = {

type CreateSubOrgResponse = {
subOrgId: string;
privateKeyId: string;
privateKeyAddress: string;
};

type ErrorMessage = {
Expand All @@ -42,7 +44,9 @@ export default async function createUser(
});

try {
const createSubOrgActivity = await activityPoller({
const privateKeyName = `Default ETH Key`;

const completedActivity = await activityPoller({
type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V3",
timestampMs: String(Date.now()),
organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
Expand All @@ -51,7 +55,7 @@ export default async function createUser(
rootQuorumThreshold: 1,
rootUsers: [
{
userName: "My new user",
userName: "New user",
apiKeys: [],
authenticators: [
{
Expand All @@ -62,16 +66,32 @@ export default async function createUser(
],
},
],
privateKeys: [],
privateKeys: [
{
privateKeyName,
curve: "CURVE_SECP256K1",
addressFormats: ["ADDRESS_FORMAT_ETHEREUM"],
privateKeyTags: [],
},
],
},
});

const subOrgId = refineNonNull(
createSubOrgActivity.result.createSubOrganizationResult?.subOrganizationId
completedActivity.result.createSubOrganizationResultV3?.subOrganizationId
);
const privateKeys = refineNonNull(
completedActivity.result.createSubOrganizationResultV3?.privateKeys
);
const privateKeyId = refineNonNull(privateKeys?.[0]?.privateKeyId);
const privateKeyAddress = refineNonNull(
privateKeys?.[0]?.addresses?.[0]?.address
);

res.status(200).json({
subOrgId,
privateKeyId,
privateKeyAddress,
});
} catch (e) {
console.error(e);
Expand Down
51 changes: 51 additions & 0 deletions examples/with-federated-passkeys/src/pages/api/getActivity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { TurnkeyApiTypes, TurnkeyClient } from "@turnkey/http";
import { ApiKeyStamper } from "@turnkey/api-key-stamper";

type TActivityResponse = TurnkeyApiTypes["v1ActivityResponse"];

type GetActivityRequest = {
organizationId: string;
activityId: string;
};

type ErrorMessage = {
message: string;
};

// this getter can be performed by the parent org
export default async function getActivity(
req: NextApiRequest,
res: NextApiResponse<TActivityResponse | ErrorMessage>
) {
const getActivityRequest = req.body as GetActivityRequest;

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

const { organizationId, activityId } = getActivityRequest;

try {
const activityResponse = await turnkeyClient.getActivity({
organizationId,
activityId,
});

res.status(200).json({
activity: activityResponse.activity,
});
} catch (e) {
console.error(e);

res.status(500).json({
message: "Something went wrong.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interpolate e?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will leave it out and just handle on the server side for now. don't feel too strongly either way 🤷

});
}

res.json;
}
72 changes: 72 additions & 0 deletions examples/with-federated-passkeys/src/pages/api/getPrivateKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { TurnkeyApiTypes, TurnkeyClient } from "@turnkey/http";
import { ApiKeyStamper } from "@turnkey/api-key-stamper";

type TPrivateKey = TurnkeyApiTypes["v1PrivateKey"];

type TFormattedPrivateKey = {
privateKeyId: string;
privateKeyName: string;
privateKeyAddress: string;
};

type GetPrivateKeysRequest = {
organizationId: string;
};

type GetPrivateKeysResponse = {
privateKeys: TFormattedPrivateKey[];
};

type ErrorMessage = {
message: string;
};

// This getter _can_ be performed by the parent org
export default async function getPrivateKeys(
req: NextApiRequest,
res: NextApiResponse<GetPrivateKeysResponse | ErrorMessage>
) {
const getPrivateKeysRequest = req.body as GetPrivateKeysRequest;

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

const organizationId = getPrivateKeysRequest.organizationId;

try {
const privateKeysResponse = await turnkeyClient.getPrivateKeys({
organizationId,
});

// By default, the API will return private keys in descending order of create date.
// We reverse it here, so that visually the most recently created private keys will be
// added to the bottom of the list instead of the top.
const privateKeys = privateKeysResponse.privateKeys
.reverse()
emostov marked this conversation as resolved.
Show resolved Hide resolved
.map((pk: TPrivateKey) => {
return {
privateKeyId: pk.privateKeyId!,
privateKeyName: pk.privateKeyName!,
privateKeyAddress: pk.addresses[0].address!,
};
});

res.status(200).json({
privateKeys,
});
} catch (e) {
console.error(e);

res.status(500).json({
message: "Something went wrong.",
});
}

res.json;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import axios from "axios";

type TResponse = {
message: string;
activityId?: string;
};

export default async function proxyRequest(
Expand All @@ -22,6 +23,7 @@ export default async function proxyRequest(

res.status(200).json({
message: "Request successfully proxied!",
activityId: tkRes.data.activityId,
});
} catch (e) {
console.error(e);
Expand Down
28 changes: 28 additions & 0 deletions examples/with-federated-passkeys/src/pages/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@
font-family: "Inter";
}

.base {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.button {
display: inline-flex;
align-items: center;
Expand All @@ -67,3 +74,24 @@
align-items: center;
gap: 10px;
}

.baseTable {
font-family: "Inter";
width: 75%;
display: flex;
justify-content: center;
align-items: center;
}

.table {
width: 100%;
}

.td {
border-spacing: 1px;
}

.th {
padding-right: 5vw;
border-spacing: 1px;
}
Loading