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

refactor(common,cli): kms deployer gets keyId from environment #2760

Merged
merged 20 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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
6 changes: 6 additions & 0 deletions .changeset/quick-lions-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@latticexyz/common": patch
yonadaaa marked this conversation as resolved.
Show resolved Hide resolved
"@latticexyz/cli": patch
---

The key ID for deploying via KMS signer is now set in the AWS_KMS_KEY_ID environment variable, instead of with a CLI flag. Correspondingly, the flag to enable KMS signing is now a `boolean` `--kms` instead of `--awsKmsKeyId`.
yonadaaa marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion packages/cli/src/commands/dev-contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const commandModule: CommandModule<typeof devOptions, InferredOptionTypes<typeof
worldAddress,
srcDir,
salt: "0x",
awsKmsKeyId: undefined,
kms: undefined,
});
worldAddress = deploy.address;
// if there were changes while we were deploying, trigger it again
Expand Down
11 changes: 5 additions & 6 deletions packages/cli/src/runDeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export const deployOptions = {
type: "string",
desc: "The deployment salt to use. Defaults to a random salt.",
},
awsKmsKeyId: {
type: "string",
desc: "Optional AWS KMS key ID. If set, the World is deployed using a KMS signer instead of local private key.",
kms: {
type: "boolean",
desc: "Deploy the World with an AWS KMS key instead of local private key.",
},
} as const satisfies Record<string, Options>;

Expand Down Expand Up @@ -87,9 +87,8 @@ export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {
const resolvedConfig = resolveConfig({ config, forgeSourceDir: srcDir, forgeOutDir: outDir });

const account = await (async () => {
if (opts.awsKmsKeyId) {
const keyId = opts.awsKmsKeyId ?? process.env.AWS_KMS_KEY_ID;
return await kmsKeyToAccount({ keyId });
if (opts.kms) {
return await kmsKeyToAccount();
yonadaaa marked this conversation as resolved.
Show resolved Hide resolved
} else {
const privateKey = process.env.PRIVATE_KEY;
if (!privateKey) {
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/account/kms/getAddressFromKms.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address, toHex } from "viem";
import { publicKeyToAddress } from "viem/utils";
import { KMSClient, SignCommandInput } from "@aws-sdk/client-kms";
import { GetPublicKeyCommandInput, KMSClient } from "@aws-sdk/client-kms";
import { getPublicKey } from "./getPublicKey";
// @ts-expect-error Could not find a declaration file for module 'asn1.js'.
import asn1 from "asn1.js";
Expand All @@ -25,7 +25,7 @@ export async function getAddressFromKms({
keyId,
client,
}: {
keyId: SignCommandInput["KeyId"];
keyId: GetPublicKeyCommandInput["KeyId"];
Copy link
Member

Choose a reason for hiding this comment

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

ooc what does this type resolve to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's string | undefined (same as SignCommandInput actually). I don't know why they make it optional! https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-kms/Interface/GetPublicKeyCommandInput/

Copy link
Member

Choose a reason for hiding this comment

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

oh, should we just make it a regular string and require it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can, i figured we can pipe it through the same way they do. I copied that approach from the ethers signer https://github.com/rumblefishdev/eth-signer-kms/blob/master/src/kms.ts#L16

Copy link
Contributor Author

Choose a reason for hiding this comment

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

also this change is totally orthogonal to the point of this PR, it's just a small consistency refactor I noticed and threw in

Copy link
Member

Choose a reason for hiding this comment

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

I thought we had it as string before, not sure when it changed

client: KMSClient;
}): Promise<Address> {
const KMSKey = await getPublicKey({ keyId, client });
Expand Down
11 changes: 8 additions & 3 deletions packages/common/src/account/kms/kmsKeyToAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { LocalAccount, hashMessage, hashTypedData, keccak256, serializeTransacti
import { toAccount } from "viem/accounts";
import { signWithKms } from "./signWithKms";
import { getAddressFromKms } from "./getAddressFromKms";
import { MUDError } from "../../errors";

export type KmsKeyToAccountOptions = {
keyId: string;
keyId?: string;
client?: KMSClient;
};

Expand All @@ -19,11 +20,15 @@ export type KmsAccount = LocalAccount<"aws-kms"> & {
* @returns A Local Account.
*/
export async function kmsKeyToAccount({
keyId,
keyId = process.env.AWS_KMS_KEY_ID,
yonadaaa marked this conversation as resolved.
Show resolved Hide resolved
client = new KMSClient(),
}: KmsKeyToAccountOptions): Promise<KmsAccount> {
}: KmsKeyToAccountOptions = {}): Promise<KmsAccount> {
const address = await getAddressFromKms({ keyId, client });

if (!keyId) {
throw new MUDError("Missing AWS KMS Key ID");
}
yonadaaa marked this conversation as resolved.
Show resolved Hide resolved

const account = toAccount({
address,
async signMessage({ message }) {
Expand Down
Loading