UNPKG

@vechain/sdk-network

Version:

This module serves as the standard interface connecting decentralized applications (dApps) and users to the VeChainThor blockchain

160 lines (146 loc) 5.62 kB
import { Hex, HexUInt, type Transaction } from '@vechain/sdk-core'; import { NotDelegatedTransaction } from '@vechain/sdk-errors'; import { type GetDelegationSignatureResult, type SignTransactionOptions } from '../types'; import { type HttpClient, HttpMethod } from '../../../http'; /** * Retrieves the signature of a delegation transaction from a gasPayer given the endpoint * from which to retrieve the signature. * * @see [Simple Gas Payer Standard](https://github.com/vechain/VIPs/blob/master/vips/VIP-201.md) * * @param tx - The transaction to delegate. * @param gasPayerServiceUrl - The URL of the endpoint of the gasPayer service. * @param originAddress - The address of the origin account. * @param httpClient - The HTTP client instance used for making HTTP requests. * @returns A promise that resolves to the signature of the delegation transaction. * @throws {NotDelegatedTransaction} */ const _getDelegationSignature = async ( tx: Transaction, gasPayerServiceUrl: string, originAddress: string, httpClient: HttpClient ): Promise<Uint8Array> => { const rawTx = Hex.of(tx.encoded).toString(); /** * The request body for the delegation transaction. * * @see [Obtaining Gas Payer Signature](https://github.com/vechain/VIPs/blob/master/vips/VIP-201.md#obtaining-gas-payer-signature) */ const sponsorRequestBody = { origin: originAddress, raw: rawTx }; try { const response = (await httpClient.http( HttpMethod.POST, gasPayerServiceUrl, { body: sponsorRequestBody, headers: { 'Content-Type': 'application/json' } } )) as GetDelegationSignatureResult; return HexUInt.of(response.signature.slice(2)).bytes; } catch (error) { throw new NotDelegatedTransaction( '_getDelegationSignature()', 'Delegation failed: Cannot get signature from gasPayerUrl.', { gasPayerUrl: gasPayerServiceUrl }, error ); } }; /** * Provide a set of utils for the delegation type. * It is a mutual exclusion between gasPayerPrivateKey and gasPayerServiceUrl. (@see SignTransactionOptions) * * The aim of this handler is to: * - Understand the kind of delegation and the delegation info * - Provide a method to get the delegation signature * * @param gasPayer - The gasPayer options. */ const DelegationHandler = ( gasPayer?: SignTransactionOptions | null ): { isDelegated: () => boolean; gasPayerOrUndefined: () => SignTransactionOptions | undefined; gasPayerOrNull: () => SignTransactionOptions | null; getDelegationSignatureUsingUrl: ( tx: Transaction, originAddress: string, httpClient: HttpClient ) => Promise<Uint8Array>; } => { // Check if gasPayer is undefined (null or undefined) const gasPayerIsUndefined = gasPayer === undefined || gasPayer === null; // Check if is delegated by url const isDelegatedWithUrl = !gasPayerIsUndefined && gasPayer?.gasPayerServiceUrl !== undefined; // Check if is delegated by private key const isDelegatedWithPrivateKey = !gasPayerIsUndefined && gasPayer?.gasPayerPrivateKey !== undefined; return { /** * Check if the transaction is delegated. * * @returns true if the transaction is delegated, false otherwise. */ isDelegated: (): boolean => isDelegatedWithUrl || isDelegatedWithPrivateKey, /** * Get the gasPayer options or undefined. * (if gasPayer is undefined or null). * * @returns The gasPayer options or undefined. */ gasPayerOrUndefined: (): SignTransactionOptions | undefined => gasPayerIsUndefined ? undefined : gasPayer, /** * Get the gasPayer options or null. * (if gasPayer is undefined or null). * * @returns The gasPayer options or null. */ gasPayerOrNull: (): SignTransactionOptions | null => gasPayerIsUndefined ? null : gasPayer, /** * Retrieves the signature of a delegation transaction from a gasPayer given the endpoint * from which to retrieve the signature. * * @see [Simple Gas Payer Standard](https://github.com/vechain/VIPs/blob/master/vips/VIP-201.md) * * @param tx - The transaction to delegate. * @param originAddress - The address of the origin account. * @param httpClient - The HTTP client instance used for making HTTP requests. * @returns A promise that resolves to the signature of the delegation transaction. * @throws {NotDelegatedTransaction} */ getDelegationSignatureUsingUrl: async ( tx: Transaction, originAddress: string, httpClient: HttpClient ): Promise<Uint8Array> => { // Cannot be delegated by private key if (!isDelegatedWithUrl) { throw new NotDelegatedTransaction( 'DelegationHandler.getDelegationSignatureUsingUrl()', 'Delegation with url failed: gasPayerServiceUrl is not defined.', undefined ); } return await _getDelegationSignature( tx, gasPayer?.gasPayerServiceUrl, originAddress, httpClient ); } }; }; export { DelegationHandler };