@vechain/sdk-aws-kms-adapter
Version:
This module implements the VeChain abstract signer so it is integrated with AWS KMS
1 lines • 25.8 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"]}