@vechain/sdk-aws-kms-adapter
Version:
This module implements the VeChain abstract signer so it is integrated with AWS KMS
1 lines • 25.9 kB
Source Map (JSON)
{"version":3,"sources":["../src/KMSVeChainSigner.ts","../src/KMSVeChainProvider.ts"],"names":["KMSVeChainSigner","_KMSVeChainSigner","VeChainAbstractSigner","provider","gasPayer","KMSVeChainProvider","JSONRPCInvalidParams","error","SignerMethodError","encodedPublicKey","schema","Sequence","ObjectIdentifier","BitString","parsed","verifySchema","objectIdentifier","kmsProvider","publicKey","fromGasPayerProvider","publicKeyDecoded","Address","payload","signature","hexSignature","bytesToHex","decodedSignatureWithoutRecoveryBit","secp256k1","recoveryBit","concatBytes","transactionHash","publicKeyHex","toHex","i","recoverPublicKey","transaction","originSignature","originAddress","delegatedHash","gasPayerSignature","DelegationHandler","transactionToSign","transactionBody","Transaction","Hex","transactionToSend","signedTransaction","RPC_METHODS","veChainSignature","VeChainProvider","thorClient","params","enableDelegation","KMSClient","_addressOrIndex","getPublicKeyCommand","GetPublicKeyCommand","getPublicKeyOutput","ProviderMethodError","message","command","SignCommand","SigningAlgorithmSpec","MessageType","signOutput"],"mappings":"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","file":"index.mjs","sourcesContent":["import { bytesToHex, concatBytes } from '@noble/curves/abstract/utils';\nimport { type SignatureType } from '@noble/curves/abstract/weierstrass';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { Address, Hex, Transaction } from '@vechain/sdk-core';\nimport { JSONRPCInvalidParams, SignerMethodError } from '@vechain/sdk-errors';\nimport {\n type AvailableVeChainProviders,\n DelegationHandler,\n RPC_METHODS,\n type TransactionRequestInput,\n VeChainAbstractSigner\n} from '@vechain/sdk-network';\nimport { BitString, ObjectIdentifier, Sequence, verifySchema } from 'asn1js';\nimport { recoverPublicKey, toHex } from 'viem';\nimport { KMSVeChainProvider } from './KMSVeChainProvider';\n\nclass KMSVeChainSigner extends VeChainAbstractSigner {\n private readonly kmsVeChainProvider?: KMSVeChainProvider;\n private readonly kmsVeChainGasPayerProvider?: KMSVeChainProvider;\n private readonly kmsVeChainGasPayerServiceUrl?: string;\n\n public constructor(\n provider?: AvailableVeChainProviders,\n gasPayer?: {\n provider?: AvailableVeChainProviders;\n url?: string;\n }\n ) {\n // Origin provider\n super(provider);\n if (this.provider !== undefined) {\n if (!(this.provider instanceof KMSVeChainProvider)) {\n throw new JSONRPCInvalidParams(\n 'KMSVeChainSigner.constructor',\n 'The provider must be an instance of KMSVeChainProvider.',\n { provider }\n );\n }\n this.kmsVeChainProvider = this.provider;\n }\n\n // Gas-payer provider, if any\n if (gasPayer !== undefined) {\n if (\n gasPayer.provider !== undefined &&\n gasPayer.provider instanceof KMSVeChainProvider\n ) {\n this.kmsVeChainGasPayerProvider = gasPayer.provider;\n } else if (gasPayer.url !== undefined) {\n this.kmsVeChainGasPayerServiceUrl = gasPayer.url;\n } else {\n throw new JSONRPCInvalidParams(\n 'KMSVeChainSigner.constructor',\n 'The gasPayer object is not well formed, either provider or url should be provided.',\n { gasPayer }\n );\n }\n }\n }\n\n /**\n * Connects the signer to a provider.\n * @param provider The provider to connect to.\n * @returns {this} The signer instance.\n * @override VeChainAbstractSigner.connect\n **/\n public connect(provider: AvailableVeChainProviders): this {\n try {\n return new KMSVeChainSigner(provider) as this;\n } catch (error) {\n throw new SignerMethodError(\n 'KMSVeChainSigner.connect',\n 'The signer could not be connected to the provider.',\n { provider },\n error\n );\n }\n }\n\n /**\n * Decodes the public key from the DER-encoded public key.\n * @param {Uint8Array} encodedPublicKey DER-encoded public key\n * @returns {Uint8Array} The decoded public key.\n */\n private decodePublicKey(encodedPublicKey: Uint8Array): Uint8Array {\n const schema = new Sequence({\n value: [\n new Sequence({ value: [new ObjectIdentifier()] }),\n new BitString({ name: 'objectIdentifier' })\n ]\n });\n const parsed = verifySchema(encodedPublicKey, schema);\n if (!parsed.verified) {\n throw new SignerMethodError(\n 'KMSVeChainSigner.decodePublicKey',\n `Failed to parse the encoded public key: ${parsed.result.error}`,\n { parsed }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const objectIdentifier: ArrayBuffer =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n parsed.result.objectIdentifier.valueBlock.valueHex;\n\n return new Uint8Array(objectIdentifier);\n }\n\n /**\n * Gets the DER-encoded public key from KMS and decodes it.\n * @param {KMSVeChainProvider} kmsProvider (Optional) The provider to get the public key from.\n * @returns {Uint8Array} The decoded public key.\n */\n private async getDecodedPublicKey(\n kmsProvider: KMSVeChainProvider | undefined = this.kmsVeChainProvider\n ): Promise<Uint8Array> {\n if (kmsProvider === undefined) {\n throw new JSONRPCInvalidParams(\n 'KMSVeChainSigner.getDecodedPublicKey',\n 'Thor provider is not found into the signer. Please attach a Provider to your signer instance.',\n {}\n );\n }\n const publicKey = await kmsProvider.getPublicKey();\n return this.decodePublicKey(publicKey);\n }\n\n /**\n * It returns the address associated with the signer.\n * @param {boolean} fromGasPayerProvider (Optional) If true, the provider will be the gasPayer.\n * @returns The address associated with the signer.\n */\n public async getAddress(\n fromGasPayerProvider: boolean | undefined = false\n ): Promise<string> {\n try {\n const kmsProvider = fromGasPayerProvider\n ? this.kmsVeChainGasPayerProvider\n : this.kmsVeChainProvider;\n const publicKeyDecoded =\n await this.getDecodedPublicKey(kmsProvider);\n return Address.ofPublicKey(publicKeyDecoded).toString();\n } catch (error) {\n throw new SignerMethodError(\n 'KMSVeChainSigner.getAddress',\n 'The address could not be retrieved.',\n { fromGasPayerProvider },\n error\n );\n }\n }\n\n /**\n * It builds a VeChain signature from a bytes' payload.\n * @param {Uint8Array} payload to sign.\n * @param {KMSVeChainProvider} kmsProvider The provider to sign the payload.\n * @returns {Uint8Array} The signature following the VeChain format.\n * @throws JSONRPCInvalidParams if `kmsProvider` is undefined.\n */\n private async buildVeChainSignatureFromPayload(\n payload: Uint8Array,\n kmsProvider: KMSVeChainProvider | undefined = this.kmsVeChainProvider\n ): Promise<Uint8Array> {\n if (kmsProvider === undefined) {\n throw new JSONRPCInvalidParams(\n 'KMSVeChainSigner.buildVeChainSignatureFromPayload',\n 'Thor provider is not found into the signer. Please attach a Provider to your signer instance.',\n { payload }\n );\n }\n\n // Sign the transaction hash\n const signature = await kmsProvider.sign(payload);\n\n // Build the VeChain signature using the r, s and v components\n const hexSignature = bytesToHex(signature);\n const decodedSignatureWithoutRecoveryBit =\n secp256k1.Signature.fromDER(hexSignature).normalizeS();\n\n const recoveryBit = await this.getRecoveryBit(\n decodedSignatureWithoutRecoveryBit,\n payload,\n kmsProvider\n );\n\n return concatBytes(\n decodedSignatureWithoutRecoveryBit.toCompactRawBytes(),\n new Uint8Array([recoveryBit])\n );\n }\n\n /**\n * Returns the recovery bit of a signature.\n * @param {SignatureType} decodedSignatureWithoutRecoveryBit Signature with the R and S components only.\n * @param {Uint8Array} transactionHash Raw transaction hash.\n * @param {KMSVeChainProvider} kmsProvider The provider to sign the payload.\n * @returns {number} The V component of the signature (either 0 or 1).\n */\n private async getRecoveryBit(\n decodedSignatureWithoutRecoveryBit: SignatureType,\n transactionHash: Uint8Array,\n kmsProvider: KMSVeChainProvider\n ): Promise<number> {\n const publicKey = await this.getDecodedPublicKey(kmsProvider);\n const publicKeyHex = toHex(publicKey);\n\n for (let i = 0n; i < 2n; i++) {\n const publicKeyRecovered = await recoverPublicKey({\n hash: transactionHash,\n signature: {\n r: toHex(decodedSignatureWithoutRecoveryBit.r),\n s: toHex(decodedSignatureWithoutRecoveryBit.s),\n v: i\n }\n });\n if (publicKeyRecovered === publicKeyHex) {\n return Number(i);\n }\n }\n\n throw new SignerMethodError(\n 'KMSVeChainSigner.getRecoveryBit',\n 'The recovery bit could not be found.',\n { decodedSignatureWithoutRecoveryBit, transactionHash }\n );\n }\n\n /**\n * Processes a transaction by signing its hash with the origin key and, if delegation is available,\n * appends a gas payer's signature to the original signature.\n *\n * @param {Transaction} transaction - The transaction to be processed, provides the transaction hash and necessary details.\n * @return {Promise<Uint8Array>} A Promise that resolves to a byte array containing the combined origin and gas payer signatures,\n * or just the origin signature if no gas payer provider or service URL is available.\n * @throws JSONRPCInvalidParams if {@link this.provider} is undefined.\n */\n private async concatSignatureIfDelegation(\n transaction: Transaction\n ): Promise<Uint8Array> {\n // Get the transaction hash\n const transactionHash = transaction.getTransactionHash().bytes;\n\n // Sign the transaction hash using origin key\n const originSignature =\n await this.buildVeChainSignatureFromPayload(transactionHash);\n\n // We try first in case there is a gasPayer provider\n if (this.kmsVeChainGasPayerProvider !== undefined) {\n const publicKeyDecoded = await this.getDecodedPublicKey();\n const originAddress = Address.ofPublicKey(publicKeyDecoded);\n const delegatedHash =\n transaction.getTransactionHash(originAddress).bytes;\n const gasPayerSignature =\n await this.buildVeChainSignatureFromPayload(\n delegatedHash,\n this.kmsVeChainGasPayerProvider\n );\n return concatBytes(originSignature, gasPayerSignature);\n } else if (\n // If not, we try with the gasPayer URL\n this.kmsVeChainGasPayerServiceUrl !== undefined\n ) {\n const originAddress = await this.getAddress();\n const gasPayerSignature = await DelegationHandler({\n gasPayerServiceUrl: this.kmsVeChainGasPayerServiceUrl\n }).getDelegationSignatureUsingUrl(\n transaction,\n originAddress,\n // Calling `buildVeChainSignatureFromPayload(transactionHash)` above throws error is `this.provider` is undefined.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.provider!.thorClient.httpClient // Never undefined.\n );\n\n return concatBytes(originSignature, gasPayerSignature);\n }\n\n return originSignature;\n }\n\n /**\n * It signs a transaction.\n * @param transactionToSign Transaction body to sign in plain format.\n * @returns {string} The signed transaction in hexadecimal format.\n * @throws JSONRPCInvalidParams if {@link this.provider} is undefined.\n */\n public async signTransaction(\n transactionToSign: TransactionRequestInput\n ): Promise<string> {\n try {\n // Populate the call, to get proper from and to address (compatible with multi-clause transactions)\n const transactionBody =\n await this.populateTransaction(transactionToSign);\n\n // Get the transaction object\n const transaction = Transaction.of(transactionBody);\n\n // Sign the transaction hash using delegation if needed\n const signature =\n await this.concatSignatureIfDelegation(transaction);\n\n return Hex.of(\n Transaction.of(transactionBody, signature).encoded\n ).toString();\n } catch (error) {\n throw new SignerMethodError(\n 'KMSVeChainSigner.signTransaction',\n 'The transaction could not be signed.',\n { transactionToSign },\n error\n );\n }\n }\n\n /**\n * Submits a signed transaction to the network.\n * @param transactionToSend Transaction to be signed and sent to the network.\n * @returns {string} The transaction ID.\n */\n public async sendTransaction(\n transactionToSend: TransactionRequestInput\n ): Promise<string> {\n try {\n // Sign the transaction\n const signedTransaction =\n await this.signTransaction(transactionToSend);\n\n // Send the signed transaction (the provider will always exist if it gets to this point)\n return (await this.kmsVeChainProvider?.request({\n method: RPC_METHODS.eth_sendRawTransaction,\n params: [signedTransaction]\n })) as string;\n } catch (error) {\n throw new SignerMethodError(\n 'KMSVeChainSigner.sendTransaction',\n 'The transaction could not be sent.',\n { transactionToSend },\n error\n );\n }\n }\n\n /**\n * Signs a bytes payload returning the VeChain signature in hexadecimal format.\n * @param {Uint8Array} payload in bytes to sign.\n * @returns {string} The VeChain signature in hexadecimal format.\n */\n public async signPayload(payload: Uint8Array): Promise<string> {\n const veChainSignature =\n await this.buildVeChainSignatureFromPayload(payload);\n // SCP256K1 encodes the recovery flag in the last byte. EIP-191 adds 27 to it.\n veChainSignature[veChainSignature.length - 1] += 27;\n return Hex.of(veChainSignature).toString();\n }\n}\n\nexport { KMSVeChainSigner };\n","import {\n GetPublicKeyCommand,\n KMSClient,\n MessageType,\n SignCommand,\n SigningAlgorithmSpec\n} from '@aws-sdk/client-kms';\nimport { ProviderMethodError } from '@vechain/sdk-errors';\nimport {\n type ThorClient,\n VeChainProvider,\n type VeChainSigner\n} from '@vechain/sdk-network';\nimport { KMSVeChainSigner } from './KMSVeChainSigner';\n\ninterface KMSClientParameters {\n keyId: string;\n region: string;\n credentials?: {\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken?: string;\n };\n endpoint?: string;\n}\n\nclass KMSVeChainProvider extends VeChainProvider {\n private readonly kmsClient: KMSClient;\n private readonly keyId: string;\n private signer?: KMSVeChainSigner;\n\n /**\n * Creates a new instance of KMSVeChainProvider.\n * @param thorClient The thor client instance to use.\n * @param params The parameters to configure the KMS client and the keyId.\n * @param enableDelegation Whether to enable delegation or not.\n **/\n public constructor(\n thorClient: ThorClient,\n params: KMSClientParameters,\n enableDelegation: boolean = false\n ) {\n super(thorClient, undefined, enableDelegation);\n this.keyId = params.keyId;\n this.kmsClient =\n params.endpoint !== undefined\n ? new KMSClient({\n region: params.region,\n endpoint: params.endpoint,\n credentials: params.credentials\n })\n : params.credentials !== undefined\n ? new KMSClient({\n region: params.region,\n credentials: params.credentials\n })\n : new KMSClient({ region: params.region });\n }\n\n /**\n * Returns a new instance of the KMSVeChainSigner using this provider configuration.\n * @param _addressOrIndex Unused parameter, will always return the signer associated to the keyId\n * @returns {KMSVeChainSigner} An instance of KMSVeChainSigner\n */\n public override async getSigner(\n _addressOrIndex?: string | number\n ): Promise<VeChainSigner | null> {\n if (this.signer !== undefined) {\n return this.signer;\n }\n this.signer = new KMSVeChainSigner(this);\n return await Promise.resolve(this.signer);\n }\n\n /**\n * Returns the public key associated with the keyId provided in the constructor.\n * @returns {Uint8Array} The public key associated with the keyId\n */\n public async getPublicKey(): Promise<Uint8Array> {\n const getPublicKeyCommand = new GetPublicKeyCommand({\n KeyId: this.keyId\n });\n const getPublicKeyOutput =\n await this.kmsClient.send(getPublicKeyCommand);\n\n if (getPublicKeyOutput.PublicKey === undefined) {\n throw new ProviderMethodError(\n 'KMSVeChainProvider.getPublicKey',\n 'The public key could not be retrieved.',\n { getPublicKeyOutput }\n );\n }\n return getPublicKeyOutput.PublicKey;\n }\n\n /**\n * Performs a sign operation using the keyId provided in the constructor.\n * @param {Uint8Array} message Message to sign using KMS\n * @returns {Uint8Array} The signature of the message\n */\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n const command = new SignCommand({\n KeyId: this.keyId,\n Message: message,\n SigningAlgorithm: SigningAlgorithmSpec.ECDSA_SHA_256,\n MessageType: MessageType.DIGEST\n });\n\n const signOutput = await this.kmsClient.send(command);\n\n if (signOutput.Signature === undefined) {\n throw new ProviderMethodError(\n 'KMSVeChainProvider.sign',\n 'The signature could not be generated.',\n { signOutput }\n );\n }\n\n return signOutput.Signature;\n }\n}\n\nexport { KMSVeChainProvider, type KMSClientParameters };\n"]}