Skip to content

Commit

Permalink
setup foundations
Browse files Browse the repository at this point in the history
  • Loading branch information
d4mr committed Nov 6, 2024
1 parent ba59e74 commit f89c8f7
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 29 deletions.
30 changes: 30 additions & 0 deletions src/db/configuration/getConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Static } from "@sinclair/typebox";
import { LocalWallet } from "@thirdweb-dev/wallets";
import { ethers } from "ethers";
import type { Chain } from "thirdweb";
import { z } from "zod";
import type {
AwsWalletConfiguration,
GcpWalletConfiguration,
Expand All @@ -17,6 +18,17 @@ import { logger } from "../../utils/logger";
import { prisma } from "../client";
import { updateConfiguration } from "./updateConfiguration";

const circleCredentialSchema = z.object({
apiKey: z.string(),
entitySecret: z.string(),
});

export type CircleCredential = z.infer<typeof circleCredentialSchema>;

export const walletProviderCredentialsSchema = z.object({
cirlce: circleCredentialSchema.optional(),
});

const toParsedConfig = async (config: Configuration): Promise<ParsedConfig> => {
// We destructure the config to omit wallet related fields to prevent direct access
const {
Expand All @@ -29,6 +41,7 @@ const toParsedConfig = async (config: Configuration): Promise<ParsedConfig> => {
gcpApplicationCredentialEmail,
gcpApplicationCredentialPrivateKey,
contractSubscriptionsRetryDelaySeconds,
walletProviderCredentials,
...restConfig
} = config;

Expand Down Expand Up @@ -162,6 +175,22 @@ const toParsedConfig = async (config: Configuration): Promise<ParsedConfig> => {
legacyWalletType_removeInNextBreakingChange = WalletType.gcpKms;
}

const otherCredentials = walletProviderCredentialsSchema.parse(
walletProviderCredentials,
);

let circleCredentials: CircleCredential | null = null;

if (otherCredentials.cirlce) {
circleCredentials = {
apiKey: otherCredentials.cirlce.apiKey,
entitySecret: decrypt(
otherCredentials.cirlce.entitySecret,
env.ENCRYPTION_PASSWORD,
),
};
}

return {
...restConfig,
contractSubscriptionsRequeryDelaySeconds:
Expand All @@ -170,6 +199,7 @@ const toParsedConfig = async (config: Configuration): Promise<ParsedConfig> => {
walletConfiguration: {
aws: awsWalletConfiguration,
gcp: gcpWalletConfiguration,
circle: circleCredentials,
legacyWalletType_removeInNextBreakingChange,
},
};
Expand Down
35 changes: 25 additions & 10 deletions src/db/configuration/updateConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
import type { Prisma } from "@prisma/client";
import { encrypt } from "../../utils/crypto";
import { prisma } from "../client";
import { walletProviderCredentialsSchema } from "./getConfiguration";

export const updateConfiguration = async (
data: Prisma.ConfigurationUpdateArgs["data"],
) => {
// ecnrypt AWS credential data
if (typeof data.awsSecretAccessKey === "string") {
data.awsSecretAccessKey = encrypt(data.awsSecretAccessKey);
}

// ecnrypt GCP credential data
if (typeof data.gcpApplicationCredentialPrivateKey === "string") {
data.gcpApplicationCredentialPrivateKey = encrypt(
data.gcpApplicationCredentialPrivateKey,
);
}

const walletProviderCredentials = walletProviderCredentialsSchema.parse(
data.walletProviderCredentials,
);

// Encrypt Circle credential data
if (walletProviderCredentials.cirlce) {
walletProviderCredentials.cirlce.entitySecret = encrypt(
walletProviderCredentials.cirlce.entitySecret,
);
}

return prisma.configuration.update({
where: {
id: "default",
},
data: {
...data,
...(typeof data.awsSecretAccessKey === "string"
? { awsSecretAccessKey: encrypt(data.awsSecretAccessKey) }
: {}),
...(typeof data.gcpApplicationCredentialPrivateKey === "string"
? {
gcpApplicationCredentialPrivateKey: encrypt(
data.gcpApplicationCredentialPrivateKey,
),
}
: {}),
walletProviderCredentials,
},
});
};
46 changes: 27 additions & 19 deletions src/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,30 @@ model Configuration {
contractSubscriptionsRetryDelaySeconds String @default("10") @map("contractSubscriptionsRetryDelaySeconds")
// AWS
awsAccessKeyId String? @map("awsAccessKeyId") /// global config, precedence goes to WalletDetails
awsSecretAccessKey String? @map("awsSecretAccessKey") /// global config, precedence goes to WalletDetails
awsRegion String? @map("awsRegion") /// global config, treat as "default", store in WalletDetails.awsKmsArn
awsAccessKeyId String? @map("awsAccessKeyId") /// global config, precedence goes to WalletDetails
awsSecretAccessKey String? @map("awsSecretAccessKey") /// global config, precedence goes to WalletDetails
awsRegion String? @map("awsRegion") /// global config, treat as "default", store in WalletDetails.awsKmsArn
// GCP
gcpApplicationProjectId String? @map("gcpApplicationProjectId") /// global config, treat as "default", store in WalletDetails.gcpKmsResourcePath
gcpKmsLocationId String? @map("gcpKmsLocationId") /// global config, treat as "default", store in WalletDetails.gcpKmsResourcePath
gcpKmsKeyRingId String? @map("gcpKmsKeyRingId") /// global config, treat as "default", store in WalletDetails.gcpKmsResourcePath
gcpApplicationCredentialEmail String? @map("gcpApplicationCredentialEmail") /// global config, precedence goes to WalletDetails
gcpApplicationCredentialPrivateKey String? @map("gcpApplicationCredentialPrivateKey") /// global config, precedence goes to WalletDetails
gcpApplicationProjectId String? @map("gcpApplicationProjectId") /// global config, treat as "default", store in WalletDetails.gcpKmsResourcePath
gcpKmsLocationId String? @map("gcpKmsLocationId") /// global config, treat as "default", store in WalletDetails.gcpKmsResourcePath
gcpKmsKeyRingId String? @map("gcpKmsKeyRingId") /// global config, treat as "default", store in WalletDetails.gcpKmsResourcePath
gcpApplicationCredentialEmail String? @map("gcpApplicationCredentialEmail") /// global config, precedence goes to WalletDetails
gcpApplicationCredentialPrivateKey String? @map("gcpApplicationCredentialPrivateKey") /// global config, precedence goes to WalletDetails
// other wallet provider credentials
walletProviderCredentials Json @default("{}") @map("walletProviderCredentials") /// GCP and AWS credentials are stored as rows in WalletDetails, but other providers are stored here
// Auth
authDomain String @default("") @map("authDomain") // TODO: Remove defaults on major
authWalletEncryptedJson String @default("") @map("authWalletEncryptedJson") // TODO: Remove defaults on major
authDomain String @default("") @map("authDomain") // TODO: Remove defaults on major
authWalletEncryptedJson String @default("") @map("authWalletEncryptedJson") // TODO: Remove defaults on major
// Webhook
webhookUrl String? @map("webhookUrl")
webhookAuthBearerToken String? @map("webhookAuthBearerToken")
webhookUrl String? @map("webhookUrl")
webhookAuthBearerToken String? @map("webhookAuthBearerToken")
// Wallet balance
minWalletBalance String @default("20000000000000000") @map("minWalletBalance")
accessControlAllowOrigin String @default("https://thirdweb.com,https://embed.ipfscdn.io") @map("accessControlAllowOrigin")
ipAllowlist String[] @default([]) @map("ipAllowlist")
clearCacheCronSchedule String @default("*/30 * * * * *") @map("clearCacheCronSchedule")
minWalletBalance String @default("20000000000000000") @map("minWalletBalance")
accessControlAllowOrigin String @default("https://thirdweb.com,https://embed.ipfscdn.io") @map("accessControlAllowOrigin")
ipAllowlist String[] @default([]) @map("ipAllowlist")
clearCacheCronSchedule String @default("*/30 * * * * *") @map("clearCacheCronSchedule")
@@map("configuration")
}
Expand Down Expand Up @@ -94,10 +98,14 @@ model WalletDetails {
gcpKmsResourcePath String? @map("gcpKmsResourcePath") @db.Text
gcpApplicationCredentialEmail String? @map("gcpApplicationCredentialEmail") /// if not available, default to: Configuration.gcpApplicationCredentialEmail
gcpApplicationCredentialPrivateKey String? @map("gcpApplicationCredentialPrivateKey") /// if not available, default to: Configuration.gcpApplicationCredentialPrivateKey
// other types of credentials
credentials Json? @map("credentials")
// Smart Backend Wallet
accountSignerAddress String? @map("accountSignerAddress") /// this, and either local, aws or gcp encryptedJson, are required for smart wallet
accountFactoryAddress String? @map("accountFactoryAddress") /// optional even for smart wallet, if not available default factory will be used
entrypointAddress String? @map("entrypointAddress") /// optional even for smart wallet, if not available SDK will use default entrypoint
accountSignerAddress String? @map("accountSignerAddress") /// this, and either local, aws or gcp encryptedJson, are required for smart wallet
accountFactoryAddress String? @map("accountFactoryAddress") /// optional even for smart wallet, if not available default factory will be used
entrypointAddress String? @map("entrypointAddress") /// optional even for smart wallet, if not available SDK will use default entrypoint
@@map("wallet_details")
}
Expand Down
3 changes: 3 additions & 0 deletions src/schema/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Configuration } from "@prisma/client";
import type { Chain } from "thirdweb";
import type { CircleCredential } from "../db/configuration/getConfiguration";
import type { WalletType } from "./wallet";

export type AwsWalletConfiguration = {
Expand Down Expand Up @@ -32,11 +33,13 @@ export interface ParsedConfig
| "gcpKmsKeyRingId"
| "gcpApplicationCredentialEmail"
| "gcpApplicationCredentialPrivateKey"
| "walletProviderCredentials"
| "contractSubscriptionsRetryDelaySeconds"
> {
walletConfiguration: {
aws: AwsWalletConfiguration | null;
gcp: GcpWalletConfiguration | null;
circle: CircleCredential | null;
legacyWalletType_removeInNextBreakingChange: WalletType;
};
contractSubscriptionsRequeryDelaySeconds: string;
Expand Down

0 comments on commit f89c8f7

Please sign in to comment.