From ffcc76944e2d8fd6c25c71699e1660154d0a24a8 Mon Sep 17 00:00:00 2001 From: MantisClone Date: Thu, 20 Jun 2024 13:35:23 -0400 Subject: [PATCH 1/2] Add script to create eth fee proxy request --- package.json | 1 + src/createRequestNative.js | 74 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/createRequestNative.js diff --git a/package.json b/package.json index a1293e9..1d6a7a6 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "prepare": "husky install", "retrieve": "node src/retrieveRequest.js", "create": "node src/createRequest.js", + "create-native": "node src/createRequestNative.js", "pay": "node src/payRequest.js" }, "author": "", diff --git a/src/createRequestNative.js b/src/createRequestNative.js new file mode 100644 index 0000000..20b29e5 --- /dev/null +++ b/src/createRequestNative.js @@ -0,0 +1,74 @@ +(async () => { + const { + RequestNetwork, + Types, + Utils, + } = require("@requestnetwork/request-client.js"); + const { + EthereumPrivateKeySignatureProvider, + } = require("@requestnetwork/epk-signature"); + const { config } = require("dotenv"); + const { Wallet } = require("ethers"); + + // Load environment variables from .env file + config(); + + const epkSignatureProvider = new EthereumPrivateKeySignatureProvider({ + method: Types.Signature.METHOD.ECDSA, + privateKey: process.env.PAYEE_PRIVATE_KEY, // Must include 0x prefix + }); + + const requestClient = new RequestNetwork({ + nodeConnectionConfig: { + baseURL: "https://sepolia.gateway.request.network/", + }, + signatureProvider: epkSignatureProvider, + }); + + // In this example, the payee is also the payer and payment recipient. + const payeeIdentity = new Wallet(process.env.PAYEE_PRIVATE_KEY).address; + const payerIdentity = payeeIdentity; + const paymentRecipient = payeeIdentity; + const feeRecipient = "0x0000000000000000000000000000000000000000"; + + const requestCreateParameters = { + requestInfo: { + currency: { + type: Types.RequestLogic.CURRENCY.ETH, + value: "ETH", + network: "sepolia", + }, + expectedAmount: "1000000000000000000", + payee: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: payeeIdentity, + }, + payer: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: payerIdentity, + }, + timestamp: Utils.getCurrentTimestampInSecond(), + }, + paymentNetwork: { + id: Types.Extension.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT, + parameters: { + paymentNetworkName: "sepolia", + paymentAddress: paymentRecipient, + feeAddress: feeRecipient, + feeAmount: "0", + }, + }, + contentData: { + reason: "🍕", + dueDate: "2023.06.16", + }, + signer: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: payeeIdentity, + }, + }; + + const request = await requestClient.createRequest(requestCreateParameters); + const requestData = await request.waitForConfirmation(); + console.log(JSON.stringify(requestData)); +})(); From e046d6b3a8f8a090946dd2c46c629ebc4417dfaa Mon Sep 17 00:00:00 2001 From: MantisClone Date: Thu, 20 Jun 2024 13:43:18 -0400 Subject: [PATCH 2/2] Add payRequestNative.js --- package.json | 3 +- src/payRequest.js | 1 - src/payRequestNative.js | 134 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 src/payRequestNative.js diff --git a/package.json b/package.json index 1d6a7a6..1159939 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "retrieve": "node src/retrieveRequest.js", "create": "node src/createRequest.js", "create-native": "node src/createRequestNative.js", - "pay": "node src/payRequest.js" + "pay": "node src/payRequest.js", + "pay-native": "node src/payRequestNative.js" }, "author": "", "license": "ISC", diff --git a/src/payRequest.js b/src/payRequest.js index 67b2606..d577d12 100644 --- a/src/payRequest.js +++ b/src/payRequest.js @@ -15,7 +15,6 @@ } = require("@requestnetwork/payment-processor"); const { providers, Wallet } = require("ethers"); const { config } = require("dotenv"); - const { Wallet } = require("ethers"); // Load environment variables from .env file config(); diff --git a/src/payRequestNative.js b/src/payRequestNative.js new file mode 100644 index 0000000..012f661 --- /dev/null +++ b/src/payRequestNative.js @@ -0,0 +1,134 @@ +(async () => { + const { + RequestNetwork, + Types, + Utils, + } = require("@requestnetwork/request-client.js"); + const { + EthereumPrivateKeySignatureProvider, + } = require("@requestnetwork/epk-signature"); + const { + approveErc20, + hasSufficientFunds, + hasErc20Approval, + payRequest, + } = require("@requestnetwork/payment-processor"); + const { providers, Wallet } = require("ethers"); + const { config } = require("dotenv"); + + // Load environment variables from .env file + config(); + + const epkSignatureProvider = new EthereumPrivateKeySignatureProvider({ + method: Types.Signature.METHOD.ECDSA, + privateKey: process.env.PAYEE_PRIVATE_KEY, // Must include 0x prefix + }); + + const requestClient = new RequestNetwork({ + nodeConnectionConfig: { + baseURL: "https://sepolia.gateway.request.network/", + }, + signatureProvider: epkSignatureProvider, + }); + + const payeeIdentity = new Wallet(process.env.PAYEE_PRIVATE_KEY).address; + const payerIdentity = payeeIdentity; + const paymentRecipient = payeeIdentity; + const feeRecipient = "0x0000000000000000000000000000000000000000"; + + const requestCreateParameters = { + requestInfo: { + currency: { + type: Types.RequestLogic.CURRENCY.ETH, + value: "ETH", + network: "sepolia", + }, + expectedAmount: "100000000000000000", // 0.1 ETH + payee: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: payeeIdentity, + }, + payer: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: payerIdentity, + }, + timestamp: Utils.getCurrentTimestampInSecond(), + }, + paymentNetwork: { + id: Types.Extension.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT, + parameters: { + paymentNetworkName: "sepolia", + paymentAddress: paymentRecipient, + feeAddress: feeRecipient, + feeAmount: "0", + }, + }, + contentData: { + reason: "🍕", + dueDate: "2023.06.16", + }, + signer: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: payeeIdentity, + }, + }; + + const request = await requestClient.createRequest(requestCreateParameters); + let requestData = await request.waitForConfirmation(); + console.log(`Created Request: ${JSON.stringify(requestData)}`); + + const provider = new providers.JsonRpcProvider( + process.env.JSON_RPC_PROVIDER_URL, + ); + const payerWallet = new Wallet( + process.env.PAYER_PRIVATE_KEY, // Must have 0x prefix + provider, + ); + + console.log( + `Checking if payer ${payerWallet.address} has sufficient funds...`, + ); + const _hasSufficientFunds = await hasSufficientFunds( + requestData, + payerWallet.address, + { + provider: provider, + }, + ); + console.log(`_hasSufficientFunds = ${_hasSufficientFunds}`); + if (!_hasSufficientFunds) { + throw new Error(`Insufficient Funds: ${payerWallet.address}`); + } + + console.log( + `Checking if payer ${payerWallet.address} has sufficient approval...`, + ); + const _hasErc20Approval = await hasErc20Approval( + requestData, + payerWallet.address, + provider, + ); + console.log(`_hasErc20Approval = ${_hasErc20Approval}`); + if (!_hasErc20Approval) { + console.log(`Requesting approval...`); + const approvalTx = await approveErc20(requestData, payerWallet); + await approvalTx.wait(2); + console.log(`Approval granted. ${approvalTx.hash}`); + } + + const paymentTx = await payRequest(requestData, payerWallet); + await paymentTx.wait(2); + console.log(`Payment complete. ${paymentTx.hash}`); + + let startTime = Date.now(); + while (requestData.balance?.balance < requestData.expectedAmount) { + requestData = await request.refresh(); + console.log(`current balance = ${requestData.balance?.balance}`); + await new Promise((resolve) => setTimeout(resolve, 1000)); + // Check if 5 seconds have passed, and if so, break out of the loop + if (Date.now() - startTime >= 5000) { + console.log("Timeout: Exiting loop after 5 seconds."); + break; + } + } +})();