Skip to content

Commit

Permalink
Merge branch 'master' into feat/superfluid
Browse files Browse the repository at this point in the history
  • Loading branch information
bertux committed Feb 24, 2022
2 parents ebddc44 + c17a9ac commit 5609b46
Show file tree
Hide file tree
Showing 15 changed files with 284 additions and 64 deletions.
Expand Up @@ -17,7 +17,6 @@ The contract also ensures that the `feeAmount` amount of the ERC20 transfer will
- `address` is the payment address for payments, the refund address for refunds
- `feeAmount` is the amount of the transfer that should be paid in fees
- `feeAddress` is the address where the fee will be sent to
- `conversion path` is a list of currency hashes to perform the conversion
- `acceptedTokens` is the list of tokens addresses accepted for payments and refunds
- `network` is the network of the tokens accepted for payments and refunds
- `maxRateTimespan` is the time span maximum accepted between the payment and the rate timestamp
Expand All @@ -38,7 +37,7 @@ The contract contains one function called `transferFromWithReferenceAndFee` whic

- `to` is the destination address for the tokens
- `requestAmount` is the amount to be paid in the request currency
- `path` is the conversion path from the request currency to the payment token (see `conversion path`)
- `path` is the conversion path from the request currency to the payment token, as provided by oracles
- `paymentReference` is the reference data used to track the transfer (see `paymentReference`)
- `feeAmount` is the amount of fees to be paid in the request currency
- `feeAddress` is the destination address for the fee
Expand Down
2 changes: 2 additions & 0 deletions packages/payment-processor/src/index.ts
Expand Up @@ -12,6 +12,8 @@ export * from './payment/swap-any-to-erc20';
export * from './payment/swap-erc20';
export * from './payment/swap-erc20-fee-proxy';
export * from './payment/conversion-erc20';
export * from './payment/any-to-erc20-proxy';
export * from './payment/any-to-eth-proxy';
export * as Escrow from './payment/erc20-escrow-payment';
import * as utils from './payment/utils';

Expand Down
Expand Up @@ -30,7 +30,7 @@ import { IConversionPaymentSettings } from './index';
*/
export async function payAnyToErc20ProxyRequest(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
paymentSettings: IConversionPaymentSettings,
amount?: BigNumberish,
feeAmount?: BigNumberish,
Expand Down
2 changes: 1 addition & 1 deletion packages/payment-processor/src/payment/any-to-eth-proxy.ts
Expand Up @@ -24,7 +24,7 @@ import { getProxyAddress } from './utils';
*/
export async function payAnyToEthProxyRequest(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
paymentSettings: IConversionPaymentSettings,
amount?: BigNumberish,
feeAmount?: BigNumberish,
Expand Down
64 changes: 56 additions & 8 deletions packages/payment-processor/src/payment/conversion-erc20.ts
Expand Up @@ -6,6 +6,7 @@ import { ClientTypes } from '@requestnetwork/types';
import { ITransactionOverrides } from './transaction-overrides';
import { getProvider, getSigner, getProxyAddress } from './utils';
import { checkErc20Allowance, encodeApproveAnyErc20 } from './erc20';
import { IPreparedTransaction } from './prepared-transaction';

/**
* Processes the approval transaction of a given payment ERC20 to be spent by the conversion proxy,
Expand All @@ -25,13 +26,12 @@ export async function approveErc20ForProxyConversionIfNeeded(
minAmount: BigNumberish,
overrides?: ITransactionOverrides,
): Promise<ContractTransaction | void> {
const proxyAddress = getProxyAddress(request, AnyToERC20PaymentDetector.getDeploymentInformation);
if (
!(await checkErc20Allowance(
!(await hasErc20ApprovalForProxyConversion(
request,
ownerAddress,
proxyAddress,
signerOrProvider,
paymentTokenAddress,
signerOrProvider,
minAmount,
))
) {
Expand All @@ -44,6 +44,31 @@ export async function approveErc20ForProxyConversionIfNeeded(
}
}

/**
* Verify if a given payment ERC20 can be spent by the conversion proxy,
* @param request request to pay, used to know the network
* @param ownerAddress address of the payer
* @param paymentTokenAddress ERC20 currency used to pay
* @param signerOrProvider the web3 provider. Defaults to Etherscan.
* @param minAmount ensures the approved amount is sufficient to pay this amount
*/
export async function hasErc20ApprovalForProxyConversion(
request: ClientTypes.IRequestData,
ownerAddress: string,
paymentTokenAddress: string,
signerOrProvider: providers.Provider | Signer = getProvider(),
minAmount: BigNumberish,
): Promise<boolean> {
const proxyAddress = getProxyAddress(request, AnyToERC20PaymentDetector.getDeploymentInformation);
return checkErc20Allowance(
ownerAddress,
proxyAddress,
signerOrProvider,
paymentTokenAddress,
minAmount,
);
}

/**
* Processes the approval transaction of the payment ERC20 to be spent by the conversion proxy,
* during the fee proxy delegate call.
Expand All @@ -58,14 +83,37 @@ export async function approveErc20ForProxyConversion(
signerOrProvider: providers.Provider | Signer = getProvider(),
overrides?: ITransactionOverrides,
): Promise<ContractTransaction> {
const preparedTx = prepareApproveErc20ForProxyConversion(
request,
paymentTokenAddress,
signerOrProvider,
overrides,
);
const signer = getSigner(signerOrProvider);
const tx = await signer.sendTransaction(preparedTx);
return tx;
}

/**
* Prepare the approval transaction of the payment ERC20 to be spent by the conversion proxy,
* during the fee proxy delegate call.
* @param request request to pay, used to know the network
* @param paymentTokenAddress picked currency to pay
* @param signerOrProvider the web3 provider. Defaults to Etherscan.
* @param overrides optionally, override default transaction values, like gas.
*/
export function prepareApproveErc20ForProxyConversion(
request: ClientTypes.IRequestData,
paymentTokenAddress: string,
signerOrProvider: providers.Provider | Signer = getProvider(),
overrides?: ITransactionOverrides,
): IPreparedTransaction {
const proxyAddress = getProxyAddress(request, AnyToERC20PaymentDetector.getDeploymentInformation);
const encodedTx = encodeApproveAnyErc20(paymentTokenAddress, proxyAddress, signerOrProvider);
const signer = getSigner(signerOrProvider);
const tx = await signer.sendTransaction({
return {
data: encodedTx,
to: paymentTokenAddress,
value: 0,
...overrides,
});
return tx;
};
}
2 changes: 1 addition & 1 deletion packages/payment-processor/src/payment/erc20-fee-proxy.ts
Expand Up @@ -26,7 +26,7 @@ import { IPreparedTransaction } from './prepared-transaction';
*/
export async function payErc20FeeProxyRequest(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
amount?: BigNumberish,
feeAmount?: BigNumberish,
overrides?: ITransactionOverrides,
Expand Down
2 changes: 1 addition & 1 deletion packages/payment-processor/src/payment/erc20-proxy.ts
Expand Up @@ -24,7 +24,7 @@ import { IPreparedTransaction } from './prepared-transaction';
*/
export async function payErc20ProxyRequest(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
amount?: BigNumberish,
overrides?: ITransactionOverrides,
): Promise<ContractTransaction> {
Expand Down
31 changes: 24 additions & 7 deletions packages/payment-processor/src/payment/erc20.ts
Expand Up @@ -17,6 +17,7 @@ import {
getSigner,
validateRequest,
} from './utils';
import { IPreparedTransaction } from './prepared-transaction';

/**
* Processes a transaction to pay an ERC20 Request.
Expand All @@ -29,7 +30,7 @@ import {
*/
export async function payErc20Request(
request: ClientTypes.IRequestData,
signerOrProvider?: providers.Web3Provider | Signer,
signerOrProvider?: providers.Provider | Signer,
amount?: BigNumberish,
feeAmount?: BigNumberish,
overrides?: ITransactionOverrides,
Expand Down Expand Up @@ -122,19 +123,35 @@ export async function approveErc20IfNeeded(
*/
export async function approveErc20(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
overrides?: ITransactionOverrides,
): Promise<ContractTransaction> {
const encodedTx = encodeApproveErc20(request, signerOrProvider);
const preparedTx = prepareApproveErc20(request, signerOrProvider, overrides);
const signer = getSigner(signerOrProvider);
const tx = await signer.sendTransaction(preparedTx);
return tx;
}

/**
* Prepare the transaction to approve the proxy to spend signer's tokens to pay
* the request in its payment currency. Can be used with a Multisig contract.
* @param request request to pay
* @param provider the web3 provider. Defaults to Etherscan.
* @param overrides optionally, override default transaction values, like gas.
*/
export function prepareApproveErc20(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Provider | Signer = getProvider(),
overrides?: ITransactionOverrides,
): IPreparedTransaction {
const encodedTx = encodeApproveErc20(request, signerOrProvider);
const tokenAddress = request.currencyInfo.value;
const tx = await signer.sendTransaction({
return {
data: encodedTx,
to: tokenAddress,
value: 0,
...overrides,
});
return tx;
};
}

/**
Expand All @@ -145,7 +162,7 @@ export async function approveErc20(
*/
export function encodeApproveErc20(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
): string {
const paymentNetworkId = (getPaymentNetworkExtension(request)
?.id as unknown) as PaymentTypes.PAYMENT_NETWORK_ID;
Expand Down
3 changes: 1 addition & 2 deletions packages/payment-processor/src/payment/eth-fee-proxy.ts
Expand Up @@ -25,7 +25,7 @@ import { IPreparedTransaction } from './prepared-transaction';
*/
export async function payEthFeeProxyRequest(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
amount?: BigNumberish,
feeAmount?: BigNumberish,
overrides?: ITransactionOverrides,
Expand All @@ -38,7 +38,6 @@ export async function payEthFeeProxyRequest(
/**
* Encodes the call to pay a request through the ETH fee proxy contract, can be used with a Multisig contract.
* @param request request to pay
* @param signerOrProvider the Web3 provider, or signer. Defaults to window.ethereum.
* @param amount optionally, the amount to pay. Defaults to remaining amount of the request.
* @param feeAmountOverride optionally, the fee amount to pay. Defaults to the fee amount of the request.
*/
Expand Down
26 changes: 21 additions & 5 deletions packages/payment-processor/src/payment/eth-input-data.ts
Expand Up @@ -10,6 +10,7 @@ import {
getSigner,
validateRequest,
} from './utils';
import { IPreparedTransaction } from './prepared-transaction';

/**
* processes the transaction to pay an ETH request.
Expand All @@ -20,23 +21,38 @@ import {
*/
export async function payEthInputDataRequest(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
amount?: BigNumberish,
overrides?: ITransactionOverrides,
): Promise<ContractTransaction> {
validateRequest(request, PaymentTypes.PAYMENT_NETWORK_ID.ETH_INPUT_DATA);
const signer = getSigner(signerOrProvider);
const preparedTx = prepareEthInputDataRequest(request, amount, overrides);
const tx = await signer.sendTransaction(preparedTx);
return tx;
}

/**
* processes the transaction to pay an ETH request.
* @param request the request to pay
* @param amount optionally, the amount to pay. Defaults to remaining amount of the request.
* @param overrides optionally, override default transaction values, like gas.
*/
export function prepareEthInputDataRequest(
request: ClientTypes.IRequestData,
amount?: BigNumberish,
overrides?: ITransactionOverrides,
): IPreparedTransaction {
validateRequest(request, PaymentTypes.PAYMENT_NETWORK_ID.ETH_INPUT_DATA);
const { paymentReference, paymentAddress } = getRequestPaymentValues(request);

const amountToPay = getAmountToPay(request, amount);

const tx = await signer.sendTransaction({
return {
data: `0x${paymentReference}`,
to: paymentAddress,
value: amountToPay,
...overrides,
});
return tx;
};
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/payment-processor/src/payment/eth-proxy.ts
Expand Up @@ -22,7 +22,7 @@ import { IPreparedTransaction } from './prepared-transaction';
*/
export async function payEthProxyRequest(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
amount?: BigNumberish,
overrides?: ITransactionOverrides,
): Promise<ContractTransaction> {
Expand Down
28 changes: 22 additions & 6 deletions packages/payment-processor/src/payment/swap-any-to-erc20.ts
Expand Up @@ -13,6 +13,7 @@ import {
} from './utils';
import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency';
import { IRequestPaymentOptions } from './settings';
import { IPreparedTransaction } from './prepared-transaction';

export { ISwapSettings } from './swap-erc20-fee-proxy';

Expand All @@ -24,9 +25,26 @@ export { ISwapSettings } from './swap-erc20-fee-proxy';
*/
export async function swapToPayAnyToErc20Request(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
options: IRequestPaymentOptions,
): Promise<ContractTransaction> {
const preparedTx = prepareSwapToPayAnyToErc20Request(request, signerOrProvider, options);
const signer = getSigner(signerOrProvider);
const tx = await signer.sendTransaction(preparedTx);
return tx;
}

/**
* Processes a transaction to swap tokens and pay an ERC20 Request through a proxy with fees.
* @param request
* @param signerOrProvider the Web3 provider, or signer. Defaults to window.ethereum.
* @param options to override amount, feeAmount and transaction parameters
*/
export function prepareSwapToPayAnyToErc20Request(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Provider | Signer = getProvider(),
options: IRequestPaymentOptions,
): IPreparedTransaction {
if (!request.extensions[PaymentTypes.PAYMENT_NETWORK_ID.ANY_TO_ERC20_PROXY]) {
throw new Error(`The request must have the payment network any-to-erc20-proxy`);
}
Expand All @@ -39,15 +57,13 @@ export async function swapToPayAnyToErc20Request(

const encodedTx = encodeSwapToPayAnyToErc20Request(request, signerOrProvider, options);
const proxyAddress = erc20SwapConversionArtifact.getAddress(network);
const signer = getSigner(signerOrProvider);

const tx = await signer.sendTransaction({
return {
data: encodedTx,
to: proxyAddress,
value: 0,
...options?.overrides,
});
return tx;
};
}

/**
Expand All @@ -58,7 +74,7 @@ export async function swapToPayAnyToErc20Request(
*/
export function encodeSwapToPayAnyToErc20Request(
request: ClientTypes.IRequestData,
signerOrProvider: providers.Web3Provider | Signer = getProvider(),
signerOrProvider: providers.Provider | Signer = getProvider(),
options: IRequestPaymentOptions,
): string {
const conversionSettings = options?.conversion;
Expand Down

0 comments on commit 5609b46

Please sign in to comment.