Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
import { AdvancedLogicTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types';
import * as Types from '../../../types';
import ERC20AddressBased from './address-based';
const PAYMENT_NETWORK_ERC20_ADDRESS_BASED = ExtensionTypes.ID.PAYMENT_NETWORK_ERC20_ADDRESS_BASED;
// ERC20 DAI contract address
// TODO: currently hard-coded to DAI, should get from ERC20 token list
const erc20ContractAddress = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359';
/**
* Handle payment networks with mainnet BTC based address extension
*
* @class PaymentNetworkERC20AddressBased
*/
export default class PaymentNetworkERC20AddressBased implements Types.IPaymentNetwork {
private erc20AddressBased: ERC20AddressBased;
/**
* @param advancedLogic Instance of Advanced Logic layer, to get the extension
*/
}
if (requestState.extensions[ExtensionTypes.ID.CONTENT_DATA]) {
throw Error(`This extension has already been created`);
}
if (!extensionAction.parameters.content) {
throw Error('No content has been given for the extension content-data');
}
// Deep copy to not mutate the input parameter
const copiedExtensionState: RequestLogicTypes.IExtensionStates = Utils.deepCopy(extensionsState);
copiedExtensionState[ExtensionTypes.ID.CONTENT_DATA] = {
events: [],
id: ExtensionTypes.ID.CONTENT_DATA,
type: ExtensionTypes.TYPE.CONTENT_DATA,
values: { content: extensionAction.parameters.content },
version: CURRENT_VERSION,
};
return copiedExtensionState;
}
function applyActionToExtension(
extensionsState: RequestLogicTypes.IExtensionStates,
extensionAction: ExtensionTypes.IAction,
requestState: RequestLogicTypes.IRequest,
): RequestLogicTypes.IExtensionStates {
if (extensionAction.action !== ExtensionTypes.ContentData.ACTION.CREATE) {
throw Error(`Unknown action: ${extensionAction.action}`);
}
if (requestState.extensions[ExtensionTypes.ID.CONTENT_DATA]) {
throw Error(`This extension has already been created`);
}
if (!extensionAction.parameters.content) {
throw Error('No content has been given for the extension content-data');
}
// Deep copy to not mutate the input parameter
const copiedExtensionState: RequestLogicTypes.IExtensionStates = Utils.deepCopy(extensionsState);
copiedExtensionState[ExtensionTypes.ID.CONTENT_DATA] = {
events: [],
id: ExtensionTypes.ID.CONTENT_DATA,
type: ExtensionTypes.TYPE.CONTENT_DATA,
values: { content: extensionAction.parameters.content },
version: CURRENT_VERSION,
function createCreationAction(
creationParameters: ExtensionTypes.PnBitcoinAddressBased.ICreationParameters,
): ExtensionTypes.IAction {
if (creationParameters.paymentAddress && !isValidAddress(creationParameters.paymentAddress)) {
throw Error('paymentAddress is not a valid bitcoin address');
}
if (creationParameters.refundAddress && !isValidAddress(creationParameters.refundAddress)) {
throw Error('refundAddress is not a valid bitcoin address');
}
return AddressBased.createCreationAction(
ExtensionTypes.ID.PAYMENT_NETWORK_TESTNET_BITCOIN_ADDRESS_BASED,
creationParameters,
);
}
public async getBalance(request: RequestLogicTypes.IRequest): Promise {
const paymentNetworkId = ExtensionTypes.ID.PAYMENT_NETWORK_ERC20_PROXY_CONTRACT;
const paymentNetwork = request.extensions[paymentNetworkId];
if (!paymentNetwork) {
throw new Error(`The request do not have the extension: ${paymentNetworkId}`);
}
const paymentAddress = paymentNetwork.values.paymentAddress;
const refundAddress = paymentNetwork.values.refundAddress;
const salt = paymentNetwork.values.salt;
let payments: Types.IBalanceWithEvents = { balance: '0', events: [] };
if (paymentAddress) {
payments = await this.extractBalanceAndEvents(
request,
salt,
paymentAddress,
function createCreationAction(
creationParameters: ExtensionTypes.PnReferenceBased.ICreationParameters,
): ExtensionTypes.IAction {
if (creationParameters.paymentAddress && !isValidAddress(creationParameters.paymentAddress)) {
throw Error('paymentAddress is not a valid ethereum address');
}
if (creationParameters.refundAddress && !isValidAddress(creationParameters.refundAddress)) {
throw Error('refundAddress is not a valid ethereum address');
}
return ReferenceBased.createCreationAction(
ExtensionTypes.ID.PAYMENT_NETWORK_ETH_INPUT_DATA,
creationParameters,
);
}
request: RequestLogicTypes.IRequest,
): Promise {
if (!request.currency.network) {
request.currency.network = 'mainnet';
}
if (!supportedNetworks.includes(request.currency.network)) {
throw new Error(
`Payment network ${
request.currency.network
} not supported by ERC20 payment detection. Supported networks: ${supportedNetworks.join(
', ',
)}`,
);
}
const paymentAddress =
request.extensions[ExtensionTypes.ID.PAYMENT_NETWORK_ERC20_ADDRESS_BASED].values
.paymentAddress;
const refundAddress =
request.extensions[ExtensionTypes.ID.PAYMENT_NETWORK_ERC20_ADDRESS_BASED].values
.refundAddress;
let payments: Types.ERC20BalanceWithEvents = { balance: '0', events: [] };
if (paymentAddress) {
payments = await this.extractBalanceAndEvents(
paymentAddress,
Types.EVENTS_NAMES.PAYMENT,
request.currency.network,
request.currency.value,
);
}
let refunds: Types.ERC20BalanceWithEvents = { balance: '0', events: [] };
public applyActionToExtensions(
extensionsState: RequestLogicTypes.IExtensionStates,
extensionAction: ExtensionTypes.IAction,
requestState: RequestLogicTypes.IRequest,
actionSigner: IdentityTypes.IIdentity,
timestamp: number,
): RequestLogicTypes.IExtensionStates {
const id: ExtensionTypes.ID = extensionAction.id;
if (id === ExtensionTypes.ID.CONTENT_DATA) {
return contentData.applyActionToExtension(
extensionsState,
extensionAction,
requestState,
actionSigner,
timestamp,
);
}
if (id === ExtensionTypes.ID.PAYMENT_NETWORK_BITCOIN_ADDRESS_BASED) {
return addressBasedBtc.applyActionToExtension(
extensionsState,
extensionAction,
requestState,
actionSigner,
timestamp,
);
import { AdvancedLogicTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types';
import * as Types from '../../../types';
import BTCAddressBased from './address-based';
const PAYMENT_NETWORK_BITCOIN_ADDRESS_BASED =
ExtensionTypes.ID.PAYMENT_NETWORK_BITCOIN_ADDRESS_BASED;
const MAINNET_BITCOIN_NETWORK_ID = 0;
/**
* Handle payment networks with mainnet BTC based address extension
*
* @class PaymentNetworkBTCAddressBased
*/
export default class PaymentNetworkBTCAddressBased
implements Types.IPaymentNetwork {
private btcAddressBased: BTCAddressBased;
/**
* @param advancedLogic Instance of Advanced Logic layer, to get the extension
*/
public constructor({
advancedLogic,
function createAddPaymentAddressAction(
addPaymentAddressParameters: ExtensionTypes.PnAddressBased.IAddPaymentAddressParameters,
): ExtensionTypes.IAction {
if (
addPaymentAddressParameters.paymentAddress &&
!isValidAddress(addPaymentAddressParameters.paymentAddress)
) {
throw Error('paymentAddress is not a valid ethereum address');
}
return AddressBased.createAddPaymentAddressAction(
ExtensionTypes.ID.PAYMENT_NETWORK_ERC20_ADDRESS_BASED,
addPaymentAddressParameters,
);
}