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

Upgrade aws sdk #30

Merged
merged 3 commits into from
Oct 2, 2023
Merged
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
6,929 changes: 4,342 additions & 2,587 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
"ethers": "^5.5.4"
},
"devDependencies": {
"@aws-sdk/client-kms": "*",
"@metamask/eth-sig-util": "^4.0.1",
"@types/jest": "^28.1.0",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"aws-sdk": "*",
"eslint": "^7.29.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
Expand Down
13 changes: 7 additions & 6 deletions src/eth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { KMS } from 'aws-sdk'
import * as asn1 from 'asn1.js'
import { BigNumber, utils } from 'ethers'

Expand All @@ -24,7 +23,10 @@ const getRS = async (signParams: SignParams) => {
throw new Error('Signature is undefined.')
}

const decoded = EcdsaSigAsnParse.decode(signature.Signature, 'der')
const decoded = EcdsaSigAsnParse.decode(
Buffer.from(signature.Signature),
'der'
)

const r = BigNumber.from(`0x${decoded.r.toString('hex')}`)
let s = BigNumber.from(`0x${decoded.s.toString('hex')}`)
Expand Down Expand Up @@ -68,10 +70,9 @@ const getRecoveryParam = (
throw new Error('Failed to calculate recovery param')
}

export const getEthAddressFromPublicKey = (
publicKey: KMS.PublicKeyType
): string => {
const res = EcdsaPubKey.decode(publicKey, 'der')
export const getEthAddressFromPublicKey = (publicKey: Uint8Array): string => {
const res = EcdsaPubKey.decode(Buffer.from(publicKey))

const pubKeyBuffer: Buffer = res.pubKey.data

const address = utils.computeAddress(pubKeyBuffer)
Expand Down
37 changes: 25 additions & 12 deletions src/kms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,42 @@ import {
} from './types'
import { getEthAddressFromPublicKey } from './eth'
import { utils } from 'ethers'
import {
GetPublicKeyCommand,
GetPublicKeyCommandOutput,
SignCommand,
SignCommandOutput
} from '@aws-sdk/client-kms'

export const getPublicKey = (getPublicKeyParams: GetPublicKeyParams) => {
export const getPublicKey = (
getPublicKeyParams: GetPublicKeyParams
): Promise<GetPublicKeyCommandOutput> => {
const { keyId, kmsInstance } = getPublicKeyParams
return kmsInstance.getPublicKey({ KeyId: keyId }).promise()
const command = new GetPublicKeyCommand({ KeyId: keyId })

return kmsInstance.send(command)
}
export const getEthAddressFromKMS = async (
getEthAddressFromKMSparams: GetEthAddressFromKMSparams
) => {
): Promise<string> => {
const { keyId, kmsInstance } = getEthAddressFromKMSparams
const KMSKey = await getPublicKey({ keyId, kmsInstance })

return getEthAddressFromPublicKey(KMSKey.PublicKey)
}

export const sign = (signParams: SignParams) => {
export const sign = async (
signParams: SignParams
): Promise<SignCommandOutput> => {
const { keyId, message, kmsInstance } = signParams
const formatted = Buffer.from(utils.arrayify(message))
return kmsInstance
.sign({
KeyId: keyId,
Message: formatted,
SigningAlgorithm: 'ECDSA_SHA_256',
MessageType: 'DIGEST'
})
.promise()

const command = new SignCommand({
KeyId: keyId,
Message: formatted,
SigningAlgorithm: 'ECDSA_SHA_256',
MessageType: 'DIGEST'
})

return kmsInstance.send(command)
}
6 changes: 3 additions & 3 deletions src/signer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import AWS from 'aws-sdk'
import { KMSClient } from '@aws-sdk/client-kms'
import { utils, Signer, providers, BigNumber } from 'ethers'
import { keccak256 } from '@ethersproject/keccak256'
import { _TypedDataEncoder } from '@ethersproject/hash'
Expand All @@ -18,11 +18,11 @@ export class KMSSigner extends Signer implements TypedDataSigner {
constructor(
public provider: providers.Provider,
public keyId: string,
private kmsInstance?: AWS.KMS
private kmsInstance?: KMSClient
) {
super()
this.keyId = keyId
this.kmsInstance = kmsInstance ?? new AWS.KMS()
this.kmsInstance = kmsInstance ?? new KMSClient({})
}

async getAddress(): Promise<string> {
Expand Down
14 changes: 7 additions & 7 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { KMS } from 'aws-sdk'
import { KMSClient, SignCommandInput } from '@aws-sdk/client-kms'

export type SignParams = {
keyId: KMS.SignRequest['KeyId']
keyId: SignCommandInput['KeyId']
message: string
kmsInstance: KMS
kmsInstance: KMSClient
}

export type GetEthAddressFromKMSparams = {
keyId: KMS.SignRequest['KeyId']
kmsInstance: KMS
keyId: SignCommandInput['KeyId']
kmsInstance: KMSClient
}

export type GetPublicKeyParams = {
keyId: KMS.SignRequest['KeyId']
kmsInstance: KMS
keyId: SignCommandInput['KeyId']
kmsInstance: KMSClient
}

export type CreateSignatureParams = SignParams & {
Expand Down
25 changes: 14 additions & 11 deletions tests/signer.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import AWS from 'aws-sdk'
import { getEthAddressFromKMS, KMSSigner } from '../src'
import { utils, providers, Wallet } from 'ethers'
import {
Expand All @@ -12,28 +11,32 @@ import {
recoverTypedSignature,
SignTypedDataVersion
} from '@metamask/eth-sig-util'
import { CreateKeyCommand, KMSClient } from '@aws-sdk/client-kms'

describe('KMSSinger', () => {
let kms: AWS.KMS
let kms: KMSClient
let keyId: string
let walletAddress: string
let kmsSigner: KMSSigner
const providerUrl = process.env.GANACHE_ENDPOINT

const provider = new providers.JsonRpcProvider(providerUrl)
beforeAll(async () => {
kms = new AWS.KMS({
kms = new KMSClient({
endpoint: process.env.KMS_ENDPOINT,
region: 'local',
accessKeyId: 'AKIAXTTRUF7NU7KDMIED',
secretAccessKey: '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'
credentials: {
accessKeyId: 'AKIAXTTRUF7NU7KDMIED',
secretAccessKey: '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'
}
})

const command = new CreateKeyCommand({
KeyUsage: 'SIGN_VERIFY',
CustomerMasterKeySpec: 'ECC_SECG_P256K1'
})
const createResponse = await kms
.createKey({
KeyUsage: 'SIGN_VERIFY',
CustomerMasterKeySpec: 'ECC_SECG_P256K1'
})
.promise()

const createResponse = await kms.send(command)

keyId = createResponse.KeyMetadata.KeyId
walletAddress = await getEthAddressFromKMS({ kmsInstance: kms, keyId })
Expand Down