-
Notifications
You must be signed in to change notification settings - Fork 105
Smart Backend Wallets #709
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
Changes from 20 commits
68c21b6
05491fe
082b54a
1b87760
fc12095
aaa5691
dbc567f
941e55d
51bd785
17245a1
7bb1b80
a6ece2b
8984844
f4ec6f9
550dc14
3256832
38b46c6
3a47e77
a3957ba
ef64f4c
b5503b9
b64dff4
c1986ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,5 +26,8 @@ | |
| "noStaticOnlyClass": "off" | ||
| } | ||
| } | ||
| }, | ||
| "files": { | ||
| "ignore": ["sdk"] | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| import type { Address } from "thirdweb"; | ||
| import type { PrismaTransaction } from "../../schema/prisma"; | ||
| import { encrypt } from "../../utils/crypto"; | ||
| import { getPrismaWithPostgresTx } from "../client"; | ||
|
|
@@ -8,13 +9,17 @@ type CreateWalletDetailsParams = { | |
| address: string; | ||
| label?: string; | ||
| } & ( | ||
| | { | ||
| type: "local"; | ||
| encryptedJson: string; // ENCRYPTION IS NOT HANDLED HERE, process privatekey with legacyLocalCrytpo before passing to this function | ||
| } | ||
| | { | ||
| type: "aws-kms"; | ||
| awsKmsKeyId?: string; // depcrecated and unused, todo: remove with next breaking change | ||
| awsKmsArn: string; | ||
|
|
||
| awsKmsSecretAccessKey?: string; // will be encrypted and stored, pass plaintext to this function | ||
| awsKmsAccessKeyId?: string; | ||
| awsKmsSecretAccessKey: string; // will be encrypted and stored, pass plaintext to this function | ||
| awsKmsAccessKeyId: string; | ||
|
Comment on lines
+21
to
+22
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Won't making these fields non-optional be a breaking change? We could ofc update the dashboard, but it'll impact anyone in the slim chance they're automating KMS backend wallet creation.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We decided to always denormalize and store credentials in the DB row, regardless of it being an override or coming from config. Users don't have to pass it in, the route fills in this from the config. |
||
| } | ||
| | { | ||
| type: "gcp-kms"; | ||
|
|
@@ -24,11 +29,42 @@ type CreateWalletDetailsParams = { | |
| gcpKmsKeyVersionId?: string; // depcrecated and unused, todo: remove with next breaking change | ||
| gcpKmsLocationId?: string; // depcrecated and unused, todo: remove with next breaking change | ||
|
|
||
| gcpApplicationCredentialPrivateKey?: string; // encrypted | ||
| gcpApplicationCredentialEmail?: string; | ||
| gcpApplicationCredentialPrivateKey: string; // will be encrypted and stored, pass plaintext to this function | ||
| gcpApplicationCredentialEmail: string; | ||
| } | ||
| | { | ||
| type: "smart:aws-kms"; | ||
| awsKmsArn: string; | ||
| awsKmsSecretAccessKey: string; // will be encrypted and stored, pass plaintext to this function | ||
| awsKmsAccessKeyId: string; | ||
| accountSignerAddress: Address; | ||
|
|
||
| accountFactoryAddress: Address | undefined; | ||
| entrypointAddress: Address | undefined; | ||
| } | ||
| | { | ||
| type: "smart:gcp-kms"; | ||
| gcpKmsResourcePath: string; | ||
| gcpApplicationCredentialPrivateKey: string; // will be encrypted and stored, pass plaintext to this function | ||
| gcpApplicationCredentialEmail: string; | ||
| accountSignerAddress: Address; | ||
|
|
||
| accountFactoryAddress: Address | undefined; | ||
| entrypointAddress: Address | undefined; | ||
| } | ||
| | { | ||
| type: "smart:local"; | ||
| encryptedJson: string; // ENCRYPTION IS NOT HANDLED HERE, process privatekey with legacyLocalCrytpo before passing to this function | ||
| accountSignerAddress: Address; | ||
|
|
||
| accountFactoryAddress: Address | undefined; | ||
| entrypointAddress: Address | undefined; | ||
| } | ||
| ); | ||
|
|
||
| /** | ||
| * Create a new WalletDetails row in DB | ||
| */ | ||
| export const createWalletDetails = async ({ | ||
| pgtx, | ||
| ...walletDetails | ||
|
|
@@ -47,15 +83,23 @@ export const createWalletDetails = async ({ | |
| ); | ||
| } | ||
|
|
||
| if (walletDetails.type === "local") { | ||
| return prisma.walletDetails.create({ | ||
| data: { | ||
| ...walletDetails, | ||
| address: walletDetails.address.toLowerCase(), | ||
| encryptedJson: walletDetails.encryptedJson, | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| if (walletDetails.type === "aws-kms") { | ||
| return prisma.walletDetails.create({ | ||
| data: { | ||
| ...walletDetails, | ||
| address: walletDetails.address.toLowerCase(), | ||
|
|
||
| awsKmsSecretAccessKey: walletDetails.awsKmsSecretAccessKey | ||
| ? encrypt(walletDetails.awsKmsSecretAccessKey) | ||
| : undefined, | ||
| awsKmsSecretAccessKey: encrypt(walletDetails.awsKmsSecretAccessKey), | ||
| }, | ||
| }); | ||
| } | ||
|
|
@@ -66,11 +110,61 @@ export const createWalletDetails = async ({ | |
| ...walletDetails, | ||
| address: walletDetails.address.toLowerCase(), | ||
|
|
||
| gcpApplicationCredentialPrivateKey: | ||
| walletDetails.gcpApplicationCredentialPrivateKey | ||
| ? encrypt(walletDetails.gcpApplicationCredentialPrivateKey) | ||
| : undefined, | ||
| gcpApplicationCredentialPrivateKey: encrypt( | ||
| walletDetails.gcpApplicationCredentialPrivateKey, | ||
| ), | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| if (walletDetails.type === "smart:aws-kms") { | ||
| return prisma.walletDetails.create({ | ||
| data: { | ||
| ...walletDetails, | ||
|
|
||
| address: walletDetails.address.toLowerCase(), | ||
| awsKmsSecretAccessKey: encrypt(walletDetails.awsKmsSecretAccessKey), | ||
| accountSignerAddress: walletDetails.accountSignerAddress.toLowerCase(), | ||
|
|
||
| accountFactoryAddress: | ||
| walletDetails.accountFactoryAddress?.toLowerCase(), | ||
| entrypointAddress: walletDetails.entrypointAddress?.toLowerCase(), | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| if (walletDetails.type === "smart:gcp-kms") { | ||
| return prisma.walletDetails.create({ | ||
| data: { | ||
| ...walletDetails, | ||
|
|
||
| address: walletDetails.address.toLowerCase(), | ||
| accountSignerAddress: walletDetails.accountSignerAddress.toLowerCase(), | ||
|
|
||
| gcpApplicationCredentialPrivateKey: encrypt( | ||
| walletDetails.gcpApplicationCredentialPrivateKey, | ||
| ), | ||
|
|
||
| accountFactoryAddress: | ||
| walletDetails.accountFactoryAddress?.toLowerCase(), | ||
| entrypointAddress: walletDetails.entrypointAddress?.toLowerCase(), | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| if (walletDetails.type === "smart:local") { | ||
| return prisma.walletDetails.create({ | ||
| data: { | ||
| ...walletDetails, | ||
| address: walletDetails.address.toLowerCase(), | ||
| accountSignerAddress: walletDetails.accountSignerAddress.toLowerCase(), | ||
|
|
||
| accountFactoryAddress: | ||
| walletDetails.accountFactoryAddress?.toLowerCase(), | ||
| entrypointAddress: walletDetails.entrypointAddress?.toLowerCase(), | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| throw new Error("Unsupported wallet type"); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note from our convo: can you check if signing on different chains result in the same output. If so, we could default to a testnet (Sepolia?).