UNPKG

@ngraveio/ur-sign

Version:

Provides BC-UR types for signature request and response from cold wallets to hot wallets.

152 lines (151 loc) 7.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SignRequest = void 0; const bc_ur_1 = require("@ngraveio/bc-ur"); const ur_blockchain_commons_1 = require("@ngraveio/ur-blockchain-commons"); const ur_uuid_1 = require("@ngraveio/ur-uuid"); const ur_coin_identity_1 = require("@ngraveio/ur-coin-identity"); class SignRequest extends (0, bc_ur_1.registryItemFactory)({ tag: 41411, URType: 'sign-request', allowKeysNotInMap: true, keyMap: { requestId: 1, coinId: 2, derivationPath: 3, signData: 4, origin: 5, txType: 6, address: 7, }, CDDL: ` sign-request = { ?request-id: uuid, ; Identifier of the signing request coin-id: #6.41401(coin-identity), ; Provides information on the elliptic curve and the blockchain/coin ?derivation-path: #6.40304(keypath), ; Key path for signing this request sign-data: bytes, ; Transaction to be decoded by the offline signer ?origin: text, ; Origin of this sign request, e.g. wallet name ?tx-type: int .default 1 ; Specify type of transaction required for some blockchains ?address: string / bytes ; Specify sender address if not already specified in the sign-data and derivation-path } request-id = 1 coin-id = 2 derivation-path = 3 sign-data = 4 origin = 5 tx-type = 6 address=7 `, }) { constructor(data) { super(data); this.verifyInput = (input) => { const reasons = []; const response = () => ({ valid: reasons.length === 0, reasons: reasons.length > 0 ? reasons : undefined }); // If request id is provided check if it is a valid UUID if (input.requestId !== undefined) { try { //@ts-ignore new ur_uuid_1.UUID(input.requestId); } catch (error) { reasons.push(new Error('Invalid requestId: ' + error.message)); } } // Check if coin id is provided if (input.coinId == undefined || !(input.coinId instanceof ur_coin_identity_1.CoinIdentity)) { reasons.push(new Error('Coin id is required and should be of type CoinIdentity')); } // If derivation path is provided it should be a valid string or instance of Keypath if (input.derivationPath !== undefined) { if (typeof input.derivationPath !== 'string' && !(input.derivationPath instanceof ur_blockchain_commons_1.Keypath)) { reasons.push(new Error('Derivation path should be a string or instance of Keypath')); return response(); } // If derivation path is a string, try to create a Keypath instance try { const derivationPath = typeof input.derivationPath == 'string' ? new ur_blockchain_commons_1.Keypath({ path: input.derivationPath }) : input.derivationPath; if (derivationPath.getComponents().length === 0) { reasons.push(new Error('Derivation path should not be empty')); } if (!derivationPath.isOnlySimple()) { reasons.push(new Error('Derivation path mush only contain simple index components')); } } catch (error) { reasons.push(new Error('Invalid derivation path: ' + error.toString())); } } // Check if sign data is provided and is of type Buffer if (input.signData === undefined || !(input.signData instanceof Uint8Array)) { reasons.push(new Error('Sign data is required and should be of type Buffer')); } else { if (input.signData.length === 0) { reasons.push(new Error('Sign data should not be empty')); } } // If origin is provided, it should be a string if (input.origin !== undefined && typeof input.origin !== 'string') { reasons.push(new Error('Origin should be a string')); } // If tx type is provided, it should be an positive integer if (input.txType !== undefined && (!Number.isInteger(input.txType) || input.txType < 0)) { reasons.push(new Error('Tx type should be a positive integer')); } // If address is provided, it should be a string or a buffer if (input.address !== undefined && typeof input.address !== 'string' && !(input.address instanceof Uint8Array)) { reasons.push(new Error('Address should be a string or a buffer')); } return response(); }; // Getters this.getRequestId = () => this.data.requestId; this.getCoinId = () => this.data.coinId; this.getDerivationPath = () => this.data.derivationPath; this.getSignData = () => this.data.signData; this.getOrigin = () => this.data.origin; this.getTxType = () => this.data.txType; this.getAddress = () => { if (this.data.address instanceof Uint8Array) return Buffer.from(this.data.address).toString('hex'); return this.data.address; }; // Verify input const { valid, reasons } = this.verifyInput(data); if (!valid) { throw new Error(`#SignRequest Invalid input: ${reasons?.map(r => r.message).join(', ')}`); } //@ts-ignore this.data = data; // Convert signData to Buffer if (!(data.signData instanceof Buffer)) { this.data.signData = Buffer.from(data.signData); } // If no request id is provided, generate a random one if (data.requestId === undefined) { this.data.requestId = ur_uuid_1.UUID.generate(); } else { // Convert requestId to UUID if it is not already an instance of UUID if (typeof data.requestId === 'string' || data.requestId instanceof Uint8Array) { this.data.requestId = new ur_uuid_1.UUID(data.requestId); } else if (!(data.requestId instanceof ur_uuid_1.UUID)) { throw new Error('Invalid requestId. Expected a UUID, string, or Uint8Array.'); } } // If given keypath is a string, convert it to Keypath if (data.derivationPath !== undefined && typeof data.derivationPath === 'string') { this.data.derivationPath = new ur_blockchain_commons_1.Keypath({ path: data.derivationPath }); } // If coin is Ethereum and txType is not provided, set it to 1 if (data.coinId.getType() == 60) { if (data.txType === undefined) { this.data.txType = 1; } } } } exports.SignRequest = SignRequest; //# sourceMappingURL=SignRequest.js.map