Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
public async getAddressBalanceWithEvents(
bitcoinNetworkId: number,
address: string,
eventName: Types.EVENTS_NAMES,
): Promise {
const baseUrl = this.getBaseUrl(bitcoinNetworkId);
const queryUrl = `${baseUrl}/addrs/${address}`;
try {
const res = await Utils.retry(async () => fetch(queryUrl), {
maxRetries: BLOCKCYPHER_REQUEST_MAX_RETRY,
retryDelay: BLOCKCYPHER_REQUEST_RETRY_DELAY,
})();
// tslint:disable-next-line:no-magic-numbers
if (res.status >= 400) {
throw new Error(`Error ${res.status}. Bad response from server ${queryUrl}`);
}
const addressInfo = await res.json();
return this.parse(addressInfo, eventName);
} catch (err) {
// tslint:disable-next-line:no-console
console.warn(err.message || err);
return { balance: '-1', events: [] };
}
}
if (!request.payer) {
throw new Error('the request must have a payer');
}
if (!action.data.parameters.deltaAmount) {
throw new Error('deltaAmount must be given');
}
if (!Utils.amount.isValid(action.data.parameters.deltaAmount)) {
throw new Error('deltaAmount must be a string representing a positive integer');
}
const signer: IdentityTypes.IIdentity = Action.getSignerIdentityFromAction(action);
const signerRole = Request.getRoleInRequest(signer, request);
// avoid to mutate the request
let requestCopied: RequestLogicTypes.IRequest = Utils.deepCopy(request);
requestCopied = Request.pushExtensionsData(requestCopied, action.data.parameters.extensionsData);
requestCopied.events.push(generateEvent(action, timestamp, signer));
if (signerRole === RequestLogicTypes.ROLE.PAYER) {
if (request.state === RequestLogicTypes.STATE.CANCELED) {
throw new Error('the request must not be canceled');
}
// increase the expected amount and store it as string
requestCopied.expectedAmount = Utils.amount.add(
request.expectedAmount,
action.data.parameters.deltaAmount,
);
return requestCopied;
}
extensionAction: ExtensionTypes.IAction,
requestState: RequestLogicTypes.IRequest,
actionSigner: IdentityTypes.IIdentity,
timestamp: number,
): ExtensionTypes.IState {
if (extensionState.values.refundInfo) {
throw Error(`The refund instruction already given`);
}
if (!requestState.payer) {
throw Error(`The request must have a payer`);
}
if (!Utils.identity.areEqual(actionSigner, requestState.payer)) {
throw Error(`The signer must be the payer`);
}
const copiedExtensionState: ExtensionTypes.IState = Utils.deepCopy(extensionState);
// increment refundInfo
copiedExtensionState.values.refundInfo = extensionAction.parameters.refundInfo;
// update events
copiedExtensionState.events.push({
name: ExtensionTypes.PnAnyDeclarative.ACTION.ADD_REFUND_INSTRUCTION,
parameters: {
refundInfo: extensionAction.parameters.refundInfo,
},
timestamp,
});
return copiedExtensionState;
}
function pushTransaction(
block: DataAccessTypes.IBlock,
transaction: DataAccessTypes.ITransaction,
channelId: string,
topics: string[] = [],
): DataAccessTypes.IBlock {
if (transaction.data === undefined && !(transaction.encryptedData && transaction.hash)) {
throw new Error(
'The transaction is missing the data property or encryptedData and hash property',
);
}
// we don't want to modify the original block state
const copiedBlock: DataAccessTypes.IBlock = Utils.deepCopy(block);
const newTransactionPosition = copiedBlock.transactions.length;
copiedBlock.transactions.push(transaction);
// index the transaction with the channel id
copiedBlock.header.channelIds[channelId] = (
copiedBlock.header.channelIds[channelId] || []
).concat([newTransactionPosition]);
// add topics in the header
for (const topic of topics) {
copiedBlock.header.topics[channelId] = (copiedBlock.header.topics[channelId] || []).concat([
topic,
]);
}
}
if (!request.payee) {
throw new Error('the request must have a payee');
}
if (!action.data.parameters.deltaAmount) {
throw new Error('deltaAmount must be given');
}
if (!Utils.amount.isValid(action.data.parameters.deltaAmount)) {
throw new Error('deltaAmount must be a string representing a positive integer');
}
const signer: IdentityTypes.IIdentity = Action.getSignerIdentityFromAction(action);
const signerRole = Request.getRoleInRequest(signer, request);
// avoid to mutate the request
let requestCopied: RequestLogicTypes.IRequest = Utils.deepCopy(request);
requestCopied = Request.pushExtensionsData(requestCopied, action.data.parameters.extensionsData);
requestCopied.events.push(generateEvent(action, timestamp, signer));
if (signerRole === RequestLogicTypes.ROLE.PAYEE) {
if (request.state === RequestLogicTypes.STATE.CANCELED) {
throw new Error('the request must not be canceled');
}
// reduce the expected amount and store it as string or throw if the result is not valid
requestCopied.expectedAmount = Utils.amount.reduce(
request.expectedAmount,
action.data.parameters.deltaAmount,
);
return requestCopied;
}
// if request currency is a string, convert it to currency object
if (typeof requestParameters.currency === 'string') {
requestParameters.currency = stringToCurrency(requestParameters.currency);
} else {
// If ERC20, validate that the value is a checksum address
if (requestParameters.currency.type === RequestLogicTypes.CURRENCY.ERC20) {
if (!validERC20Address(requestParameters.currency.value)) {
throw new Error(
'The ERC20 currency address needs to be a valid Ethereum checksum address',
);
}
}
}
// avoid mutation of the parameters
const copiedRequestParameters = Utils.deepCopy(requestParameters);
copiedRequestParameters.extensionsData = [];
let paymentNetwork: Types.IPaymentNetwork | null = null;
if (paymentNetworkCreationParameters) {
paymentNetwork = PaymentNetworkFactory.createPaymentNetwork({
advancedLogic: this.advancedLogic,
bitcoinDetectionProvider: this.bitcoinDetectionProvider,
currency: requestParameters.currency,
paymentNetworkCreationParameters,
});
if (paymentNetwork) {
// create the extensions data for the payment network
copiedRequestParameters.extensionsData.push(
paymentNetwork.createExtensionsDataForCreation(
paymentNetworkCreationParameters.parameters,
extensionAction: ExtensionTypes.IAction,
requestState: RequestLogicTypes.IRequest,
actionSigner: IdentityTypes.IIdentity,
timestamp: number,
): ExtensionTypes.IState {
if (!requestState.payee) {
throw Error(`The request must have a payee`);
}
if (!Utils.identity.areEqual(actionSigner, requestState.payee)) {
throw Error(`The signer must be the payee`);
}
if (!Utils.amount.isValid(extensionAction.parameters.amount)) {
throw Error(`The amount is not an integer`);
}
const copiedExtensionState: ExtensionTypes.IState = Utils.deepCopy(extensionState);
// increment receivedPaymentAmount
copiedExtensionState.values.receivedPaymentAmount = Utils.amount.add(
copiedExtensionState.values.receivedPaymentAmount,
extensionAction.parameters.amount,
);
// update events
copiedExtensionState.events.push({
name: ExtensionTypes.PnAnyDeclarative.ACTION.DECLARE_RECEIVED_PAYMENT,
parameters: {
amount: extensionAction.parameters.amount,
note: extensionAction.parameters.note,
},
timestamp,
});
function applyActionToExtension(
isValidAddress: (address: string) => boolean,
extensionsState: RequestLogicTypes.IExtensionStates,
extensionAction: ExtensionTypes.IAction,
requestState: RequestLogicTypes.IRequest,
actionSigner: IdentityTypes.IIdentity,
timestamp: number,
): RequestLogicTypes.IExtensionStates {
const copiedExtensionState: RequestLogicTypes.IExtensionStates = Utils.deepCopy(extensionsState);
if (extensionAction.action === ExtensionTypes.PnAddressBased.ACTION.CREATE) {
if (requestState.extensions[extensionAction.id]) {
throw Error(`This extension has already been created`);
}
copiedExtensionState[extensionAction.id] = applyCreation(
isValidAddress,
extensionAction,
timestamp,
);
return copiedExtensionState;
}
// if the action is not "create", the state must have been created before
public addSignatureParameters(
signatureParams: SignatureTypes.ISignatureParameters,
): IdentityTypes.IIdentity {
if (!this.supportedMethods.includes(signatureParams.method)) {
throw Error(`Signing method not supported ${signatureParams.method}`);
}
// compute the address from private key
// toLowerCase to avoid mismatch because of case
const address = Utils.crypto.EcUtils.getAddressFromPrivateKey(
signatureParams.privateKey,
).toLowerCase();
this.signatureParametersDictionary.set(address, signatureParams);
return {
type: IdentityTypes.TYPE.ETHEREUM_ADDRESS,
value: address,
};
}
function calculate(requestId: string, salt: string, address: string): string {
if (!requestId || !salt || !address) {
throw new Error('RequestId, salt and address are mandatory to calculate the payment reference');
}
// "The value is the last 8 bytes of a salted hash of the requestId: `last8Bytes(hash(requestId + salt + address))`"
// tslint:disable:no-magic-numbers
return Utils.crypto.keccak256Hash((requestId + salt + address).toLowerCase()).slice(-16);
}