Skip to content

Commit 2275633

Browse files
authored
Use one wallet type and update wallet creation & import (#140)
* Upgrade wallet creation and importing * Update create examples * Remove wallets helpers * Fix GCP import
1 parent b34c436 commit 2275633

19 files changed

+617
-591
lines changed

core/env.ts

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createEnv } from "@t3-oss/env-core";
22
import * as dotenv from "dotenv";
33
import type { ZodError } from "zod";
44
import { z } from "zod";
5+
import { WalletType } from "../src/schema/wallet";
56

67
dotenv.config({
78
debug: true,
@@ -23,17 +24,36 @@ export const env = createEnv({
2324
NODE_ENV: z
2425
.enum(["production", "development", "testing", "local"])
2526
.default("development"),
26-
AWS_KMS_KEY_ID: z.string().min(1).optional(),
27-
GOOGLE_KMS_KEY_ID: z.string().min(1).optional(),
28-
AWS_ACCESS_KEY_ID: z.string().min(1).optional(),
29-
AWS_SECRET_ACCESS_KEY: z.string().min(1).optional(),
30-
AWS_REGION: z.string().min(1).optional(),
3127
THIRDWEB_API_SECRET_KEY: z.string().min(1),
3228
POSTGRES_CONNECTION_URL: z
3329
.string()
3430
.default(
3531
"postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable",
3632
),
33+
WALLET_CONFIGURATION: z.string().transform((config) =>
34+
z
35+
.union([
36+
z.object({
37+
type: z.literal(WalletType.local),
38+
}),
39+
z.object({
40+
type: z.literal(WalletType.awsKms),
41+
awsAccessKeyId: z.string().min(1),
42+
awsSecretAccessKey: z.string().min(1),
43+
awsRegion: z.string().min(1),
44+
}),
45+
z.object({
46+
type: z.literal(WalletType.gcpKms),
47+
gcpApplicationProjectId: z.string().min(1),
48+
gcpKmsLocationId: z.string().min(1),
49+
gcpKmsKeyRingId: z.string().min(1),
50+
// TODO: Are these optional?
51+
gcpApplicationCredentialEmail: z.string().min(1),
52+
gcpApplicationCredentialPrivateKey: z.string().min(1),
53+
}),
54+
])
55+
.parse(JSON.parse(config)),
56+
),
3757
OPENAPI_BASE_ORIGIN: z.string().default("http://localhost:3005"),
3858
PORT: z.coerce.number().default(3005),
3959
HOST: z.string().default("0.0.0.0"),
@@ -44,11 +64,6 @@ export const env = createEnv({
4464
MINED_TX_CRON_ENABLED: boolSchema("true"),
4565
MINED_TX_CRON_SCHEDULE: z.string().default("*/5 * * * * *"),
4666
MIN_TX_TO_CHECK_FOR_MINED_STATUS: z.coerce.number().default(50),
47-
GOOGLE_APPLICATION_PROJECT_ID: z.string().min(1).optional(),
48-
GOOGLE_KMS_KEY_RING_ID: z.string().min(1).optional(),
49-
GOOGLE_KMS_LOCATION_ID: z.string().min(1).optional(),
50-
GOOGLE_APPLICATION_CREDENTIAL_EMAIL: z.string().min(1).optional(),
51-
GOOGLE_APPLICATION_CREDENTIAL_PRIVATE_KEY: z.string().min(1).optional(),
5267
RETRY_TX_ENABLED: boolSchema("true"),
5368
MAX_FEE_PER_GAS_FOR_RETRY: z.string().default("55000000000"),
5469
MAX_PRIORITY_FEE_PER_GAS_FOR_RETRY: z.string().default("55000000000"),
@@ -62,13 +77,36 @@ export const env = createEnv({
6277
isServer: true,
6378
runtimeEnvStrict: {
6479
NODE_ENV: process.env.NODE_ENV,
65-
AWS_KMS_KEY_ID: process.env.AWS_KMS_KEY_ID,
66-
GOOGLE_KMS_KEY_ID: process.env.GOOGLE_KMS_KEY_ID,
67-
AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID,
68-
AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY,
69-
AWS_REGION: process.env.AWS_REGION,
7080
THIRDWEB_API_SECRET_KEY: process.env.THIRDWEB_API_SECRET_KEY,
7181
POSTGRES_CONNECTION_URL: process.env.POSTGRES_CONNECTION_URL,
82+
WALLET_CONFIGURATION:
83+
process.env.AWS_ACCESS_KEY_ID ||
84+
process.env.AWS_SECRET_ACCESS_KEY ||
85+
process.env.AWS_REGION
86+
? JSON.stringify({
87+
type: WalletType.awsKms,
88+
awsAccessKeyId: process.env.AWS_ACCESS_KEY_ID,
89+
awsSecretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
90+
awsRegion: process.env.AWS_REGION,
91+
})
92+
: process.env.GOOGLE_APPLICATION_PROJECT_ID ||
93+
process.env.GOOGLE_KMS_LOCATION_ID ||
94+
process.env.GOOGLE_KMS_KEY_RING_ID ||
95+
process.env.GOOGLE_APPLICATION_CREDENTIAL_EMAIL ||
96+
process.env.GOOGLE_APPLICATION_CREDENTIAL_PRIVATE_KEY
97+
? JSON.stringify({
98+
type: WalletType.gcpKms,
99+
gcpApplicationProjectId: process.env.GOOGLE_APPLICATION_PROJECT_ID,
100+
gcpKmsLocationId: process.env.GOOGLE_KMS_LOCATION_ID,
101+
gcpKmsKeyRingId: process.env.GOOGLE_KMS_KEY_RING_ID,
102+
gcpApplicationCredentialEmail:
103+
process.env.GOOGLE_APPLICATION_CREDENTIAL_EMAIL,
104+
gcpApplicationCredentialPrivateKey:
105+
process.env.GOOGLE_APPLICATION_CREDENTIAL_PRIVATE_KEY,
106+
})
107+
: JSON.stringify({
108+
type: WalletType.local,
109+
}),
72110
PORT: process.env.PORT,
73111
HOST: process.env.HOST,
74112
OPENAPI_BASE_ORIGIN: process.env.OPENAPI_BASE_ORIGIN,
@@ -80,13 +118,6 @@ export const env = createEnv({
80118
MINED_TX_CRON_SCHEDULE: process.env.MINED_TX_CRON_SCHEDULE,
81119
MIN_TX_TO_CHECK_FOR_MINED_STATUS:
82120
process.env.MIN_TX_TO_CHECK_FOR_MINED_STATUS,
83-
GOOGLE_APPLICATION_PROJECT_ID: process.env.GOOGLE_APPLICATION_PROJECT_ID,
84-
GOOGLE_KMS_KEY_RING_ID: process.env.GOOGLE_KMS_KEY_RING_ID,
85-
GOOGLE_KMS_LOCATION_ID: process.env.GOOGLE_KMS_LOCATION_ID,
86-
GOOGLE_APPLICATION_CREDENTIAL_EMAIL:
87-
process.env.GOOGLE_APPLICATION_CREDENTIAL_EMAIL,
88-
GOOGLE_APPLICATION_CREDENTIAL_PRIVATE_KEY:
89-
process.env.GOOGLE_APPLICATION_CREDENTIAL_PRIVATE_KEY,
90121
RETRY_TX_ENABLED: process.env.RETRY_TX_ENABLED,
91122
MAX_FEE_PER_GAS_FOR_RETRY: process.env.MAX_FEE_PER_GAS_FOR_RETRY,
92123
MAX_PRIORITY_FEE_PER_GAS_FOR_RETRY:

core/sdk/sdk.ts

Lines changed: 18 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import { AsyncStorage, LocalWallet } from "@thirdweb-dev/wallets";
66
import { AwsKmsWallet } from "@thirdweb-dev/wallets/evm/wallets/aws-kms";
77
import { GcpKmsSigner } from "ethers-gcp-kms-signer";
88
import * as fs from "fs";
9-
import {
10-
WalletConfigType,
11-
walletTableSchema,
12-
} from "../../server/schemas/wallet";
9+
import { walletTableSchema } from "../../server/schemas/wallet";
10+
import { getAwsKmsWallet } from "../../server/utils/wallets/getAwsKmsWallet";
11+
import { getGcpKmsSigner } from "../../server/utils/wallets/getGcpKmsSigner";
12+
import { getLocalWallet } from "../../server/utils/wallets/getLocalWallet";
1313
import { getWalletDetails } from "../../src/db/wallets/getWalletDetails";
1414
import { PrismaTransaction } from "../../src/schema/prisma";
15+
import { WalletType } from "../../src/schema/wallet";
1516
import { env } from "../env";
1617
import { networkResponseSchema } from "../schema";
1718

@@ -119,9 +120,6 @@ const getCachedWallet = async (
119120
return walletData;
120121
};
121122

122-
const AWS_REGION = env.AWS_REGION;
123-
const AWS_ACCESS_KEY_ID = env.AWS_ACCESS_KEY_ID;
124-
const AWS_SECRET_ACCESS_KEY = env.AWS_SECRET_ACCESS_KEY;
125123
const THIRDWEB_API_SECRET_KEY = env.THIRDWEB_API_SECRET_KEY;
126124

127125
export const getSDK = async (
@@ -175,85 +173,39 @@ export const getSDK = async (
175173
const gcpKmsKeyId = walletData.gcpKmsKeyId;
176174
const gcpKmsKeyVersionId = walletData.gcpKmsKeyVersionId;
177175

178-
if (walletType === WalletConfigType.aws_kms) {
179-
if (!AWS_REGION || !AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY) {
180-
throw new Error(
181-
"AWS_REGION, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY must be set in order to use AWS KMS.",
182-
);
183-
}
176+
console.log(
177+
`getSDK walletAddress: ${walletAddress}, walletType: ${walletType}, awsKmsKeyId: ${awsKmsKeyId}, gcpKmsKeyId: ${gcpKmsKeyId}, chainName: ${chainName}`,
178+
);
179+
180+
if (walletType === WalletType.awsKms) {
184181
if (!awsKmsKeyId) {
185-
throw new Error("AWS KMS Key ID must be set in order to use AWS KMS.");
182+
throw new Error("Wallet does not specify awsKmsKeyId");
186183
}
187184

188-
wallet = new AwsKmsWallet({
189-
region: AWS_REGION,
190-
accessKeyId: AWS_ACCESS_KEY_ID,
191-
secretAccessKey: AWS_SECRET_ACCESS_KEY,
192-
keyId: awsKmsKeyId,
193-
});
185+
const wallet = getAwsKmsWallet({ awsKmsKeyId });
194186
sdk = await ThirdwebSDK.fromWallet(wallet, chain, {
195187
secretKey: THIRDWEB_API_SECRET_KEY,
196188
supportedChains: RPC_OVERRIDES,
197189
});
198190
walletAddress = await sdk.wallet.getAddress();
199191
cacheSdk(chain.name, sdk, walletAddress);
200192
return sdk;
201-
} else if (walletType === WalletConfigType.gcp_kms) {
202-
// Google Service A/C credentials Check
203-
if (
204-
!env.GOOGLE_APPLICATION_CREDENTIAL_EMAIL ||
205-
!env.GOOGLE_APPLICATION_CREDENTIAL_PRIVATE_KEY
206-
) {
207-
throw new Error(
208-
`Please provide needed Google Service A/C credentials in order to use GCP KMS.
209-
Check for GOOGLE_APPLICATION_CREDENTIAL_PRIVATE_KEY and GOOGLE_APPLICATION_CREDENTIAL_EMAIL in .env file`,
210-
);
211-
}
212-
213-
if (
214-
!env.GOOGLE_KMS_KEY_RING_ID ||
215-
!env.GOOGLE_KMS_LOCATION_ID ||
216-
!env.GOOGLE_APPLICATION_PROJECT_ID
217-
) {
218-
throw new Error(
219-
"GOOGLE_APPLICATION_PROJECT_ID, GOOGLE_KMS_KEY_RING_ID, and GOOGLE_KMS_LOCATION_ID must be set in order to use GCP KMS.",
220-
);
221-
}
222-
223-
if (!gcpKmsKeyVersionId || !gcpKmsKeyId) {
193+
} else if (walletType === WalletType.gcpKms) {
194+
if (!(gcpKmsKeyId && gcpKmsKeyVersionId)) {
224195
throw new Error(
225-
"GOOGLE_KMS_KEY_VERSION_ID and GOOGLE_KMS_KEY_ID must be set in order to use GCP KMS. Please check .env file",
196+
"Wallet does not specify gcpKmsKeyId or gcpKmsKeyVersionId",
226197
);
227198
}
228199

229-
const kmsCredentials = {
230-
projectId: env.GOOGLE_APPLICATION_PROJECT_ID,
231-
locationId: env.GOOGLE_KMS_LOCATION_ID,
232-
keyRingId: env.GOOGLE_KMS_KEY_RING_ID,
233-
keyId: gcpKmsKeyId!,
234-
keyVersion: gcpKmsKeyVersionId,
235-
};
236-
237-
signer = new GcpKmsSigner(kmsCredentials);
200+
const signer = getGcpKmsSigner({ gcpKmsKeyId, gcpKmsKeyVersionId });
238201
sdk = ThirdwebSDK.fromSigner(signer, chain, {
239202
secretKey: THIRDWEB_API_SECRET_KEY,
240203
supportedChains: RPC_OVERRIDES,
241204
});
242205
cacheSdk(chain.name, sdk, walletAddress);
243206
return sdk;
244-
} else if (
245-
walletType === WalletConfigType.ppk ||
246-
walletType === WalletConfigType.local
247-
) {
248-
//TODO get private key from encrypted file
249-
wallet = new LocalWallet({
250-
chain,
251-
});
252-
await wallet.load({
253-
strategy: "encryptedJson",
254-
password: THIRDWEB_API_SECRET_KEY,
255-
storage: new LocalFileStorage(walletAddress),
256-
});
207+
} else if (walletType === WalletType.local) {
208+
const wallet = await getLocalWallet({ walletAddress });
257209
sdk = await ThirdwebSDK.fromWallet(wallet, chain, {
258210
secretKey: THIRDWEB_API_SECRET_KEY,
259211
supportedChains: RPC_OVERRIDES,

server/api/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ import { extractEvents } from "./contract/metadata/events";
3636
import { extractFunctions } from "./contract/metadata/functions";
3737

3838
// Wallet
39-
import { addWallet } from "./wallet/addWallet";
40-
import { createEOAWallet } from "./wallet/createEOAWallet";
39+
import { createWallet } from "./wallet/create";
4140
import { getAll } from "./wallet/getAll";
4241
import { getBalance } from "./wallet/getBalance";
42+
import { importWallet } from "./wallet/import";
4343

4444
export const apiRoutes = async (fastify: FastifyInstance) => {
4545
// Wallet
46-
await fastify.register(createEOAWallet);
47-
await fastify.register(addWallet);
46+
await fastify.register(createWallet);
47+
await fastify.register(importWallet);
4848
await fastify.register(getBalance);
4949
await fastify.register(getAll);
5050

0 commit comments

Comments
 (0)