Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
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
30 changes: 30 additions & 0 deletions src/shared/db/configuration/get-configuration.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 "./update-configuration";

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/shared/db/configuration/update-configuration.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";

Check failure on line 4 in src/shared/db/configuration/update-configuration.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find module './getConfiguration' or its corresponding type declarations.

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,
},
});
};
3 changes: 3 additions & 0 deletions src/shared/schemas/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";

Check failure on line 3 in src/shared/schemas/config.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find module '../db/configuration/getConfiguration' or its corresponding type declarations.
import type { WalletType } from "./wallet";

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