Skip to content

Commit c44e828

Browse files
authored
feat: add delegate declarative payment example (#10)
1 parent b552378 commit c44e828

File tree

4 files changed

+267
-1
lines changed

4 files changed

+267
-1
lines changed

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Must include 0x prefix
2+
# WARNING: These are example keys. DO NOT use them to store real funds!
3+
# Generate unique private keys for each role using a secure method
24
PAYEE_PRIVATE_KEY='0x4025da5692759add08f98f4b056c41c71916a671cedc7584a80d73adc7fb43c0'
35
PAYER_PRIVATE_KEY='0x4025da5692759add08f98f4b056c41c71916a671cedc7584a80d73adc7fb43c0'
6+
PAYEE_DELEGATE_PRIVATE_KEY='0x4025da5692759add08f98f4b056c41c71916a671cedc7584a80d73adc7fb43c0'
7+
PAYER_DELEGATE_PRIVATE_KEY='0x4025da5692759add08f98f4b056c41c71916a671cedc7584a80d73adc7fb43c0'
48

59
# Infura, Alchemy, etc.
610
JSON_RPC_PROVIDER_URL='https://eth-sepolia.g.alchemy.com/v2/demo'

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ npm run retrieve
4040
npm run create
4141
npm run pay
4242
npm run declare
43+
npm run delegate
4344
```

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"retrieve": "node src/retrieveRequest.js",
1010
"create": "node src/createRequest.js",
1111
"pay": "node src/payRequest.js",
12-
"declare": "node src/declarePaymentSentAndReceived.js"
12+
"declare": "node src/declarePaymentSentAndReceived.js",
13+
"delegate": "node src/delegateDeclarePaymentSentAndReceived.js"
1314
},
1415
"author": "",
1516
"license": "ISC",
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
const waitForConfirmation = async (dataOrPromise) => {
2+
const data = await dataOrPromise;
3+
return new Promise((resolve, reject) => {
4+
data.on("confirmed", resolve);
5+
data.on("error", reject);
6+
});
7+
};
8+
9+
(async () => {
10+
const {
11+
RequestNetwork,
12+
Types,
13+
Utils,
14+
} = require("@requestnetwork/request-client.js");
15+
const {
16+
EthereumPrivateKeySignatureProvider,
17+
} = require("@requestnetwork/epk-signature");
18+
const { config } = require("dotenv");
19+
const { Wallet } = require("ethers");
20+
21+
// Load environment variables from .env file
22+
config();
23+
24+
const payeeEpkSignatureProvider = new EthereumPrivateKeySignatureProvider({
25+
method: Types.Signature.METHOD.ECDSA,
26+
privateKey: process.env.PAYEE_PRIVATE_KEY, // Must include 0x prefix
27+
});
28+
29+
const payerEpkSignatureProvider = new EthereumPrivateKeySignatureProvider({
30+
method: Types.Signature.METHOD.ECDSA,
31+
privateKey: process.env.PAYER_PRIVATE_KEY, // Must include 0x prefix
32+
});
33+
34+
const payeeDelegateEpkSignatureProvider =
35+
new EthereumPrivateKeySignatureProvider({
36+
method: Types.Signature.METHOD.ECDSA,
37+
privateKey: process.env.PAYEE_DELEGATE_PRIVATE_KEY, // Must include 0x prefix
38+
});
39+
40+
const payerDelegateEpkSignatureProvider =
41+
new EthereumPrivateKeySignatureProvider({
42+
method: Types.Signature.METHOD.ECDSA,
43+
privateKey: process.env.PAYER_DELEGATE_PRIVATE_KEY, // Must include 0x prefix
44+
});
45+
46+
const payeeRequestClient = new RequestNetwork({
47+
nodeConnectionConfig: {
48+
baseURL: "https://sepolia.gateway.request.network/",
49+
},
50+
signatureProvider: payeeEpkSignatureProvider,
51+
});
52+
53+
const payerRequestClient = new RequestNetwork({
54+
nodeConnectionConfig: {
55+
baseURL: "https://sepolia.gateway.request.network/",
56+
},
57+
signatureProvider: payerEpkSignatureProvider,
58+
});
59+
60+
const payeeDelegateRequestClient = new RequestNetwork({
61+
nodeConnectionConfig: {
62+
baseURL: "https://sepolia.gateway.request.network/",
63+
},
64+
signatureProvider: payeeDelegateEpkSignatureProvider,
65+
});
66+
67+
const payerDelegateRequestClient = new RequestNetwork({
68+
nodeConnectionConfig: {
69+
baseURL: "https://sepolia.gateway.request.network/",
70+
},
71+
signatureProvider: payerDelegateEpkSignatureProvider,
72+
});
73+
74+
const payeeIdentityAddress = new Wallet(process.env.PAYEE_PRIVATE_KEY)
75+
.address;
76+
const payerIdentityAddress = new Wallet(process.env.PAYER_PRIVATE_KEY)
77+
.address;
78+
const payeeDelegateIdentityAddress = new Wallet(
79+
process.env.PAYEE_DELEGATE_PRIVATE_KEY,
80+
).address;
81+
const payerDelegateIdentityAddress = new Wallet(
82+
process.env.PAYER_DELEGATE_PRIVATE_KEY,
83+
).address;
84+
85+
const payeeIdentity = {
86+
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
87+
value: payeeIdentityAddress,
88+
};
89+
90+
const payerIdentity = {
91+
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
92+
value: payerIdentityAddress,
93+
};
94+
95+
const payeeDelegateIdentity = {
96+
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
97+
value: payeeDelegateIdentityAddress,
98+
};
99+
100+
const payerDelegateIdentity = {
101+
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
102+
value: payerDelegateIdentityAddress,
103+
};
104+
105+
// In this example, the payee is also the payment recipient.
106+
const paymentRecipient = payeeIdentityAddress;
107+
const feeRecipient = "0x0000000000000000000000000000000000000000";
108+
109+
const requestCreateParameters = {
110+
requestInfo: {
111+
currency: {
112+
type: Types.RequestLogic.CURRENCY.ERC20,
113+
value: "0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C", // FAU token address
114+
network: "sepolia",
115+
},
116+
expectedAmount: "1000000000000000000", // 1.0
117+
payee: payeeIdentity,
118+
payer: payerIdentity,
119+
timestamp: Utils.getCurrentTimestampInSecond(),
120+
},
121+
paymentNetwork: {
122+
// We can declare payments because ERC20 fee proxy payment network inherits from declarative payment network
123+
id: Types.Extension.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT,
124+
parameters: {
125+
paymentNetworkName: "sepolia",
126+
paymentAddress: paymentRecipient,
127+
feeAddress: feeRecipient,
128+
feeAmount: "0",
129+
},
130+
},
131+
contentData: {
132+
reason: "🍕",
133+
dueDate: "2023.06.16",
134+
builderId: "request-network",
135+
createdWith: "quickstart",
136+
},
137+
signer: payeeIdentity,
138+
};
139+
140+
const payeeRequest = await payeeRequestClient.createRequest(
141+
requestCreateParameters,
142+
);
143+
const payeeRequestData = await payeeRequest.waitForConfirmation();
144+
145+
const payeeRequestDataAfterDelegate =
146+
await payeeRequest.addDeclarativeDelegate(
147+
payeeDelegateIdentity,
148+
payeeIdentity,
149+
);
150+
console.log(
151+
"payeeRequestDataAfterDelegate: " +
152+
JSON.stringify(payeeRequestDataAfterDelegate, null, 2),
153+
);
154+
155+
const payeeRequestDataAfterDelegateConfirmed = await waitForConfirmation(
156+
payeeRequestDataAfterDelegate,
157+
);
158+
console.log(
159+
"payeeRequestDataAfterDelegateConfirmed: " +
160+
JSON.stringify(payeeRequestDataAfterDelegateConfirmed, null, 2),
161+
);
162+
console.log(
163+
"Observe that extensions.pn-erc20-fee-proxy-contract.values.payeeDelegate is set to the payee delegate identity",
164+
);
165+
166+
const payerRequest = await payerRequestClient.fromRequestId(
167+
payeeRequestData.requestId,
168+
);
169+
170+
const payerRequestDataAfterDelegate =
171+
await payerRequest.addDeclarativeDelegate(
172+
payerDelegateIdentity,
173+
payerIdentity,
174+
);
175+
console.log(
176+
"payerRequestDataAfterDelegate: " +
177+
JSON.stringify(payerRequestDataAfterDelegate, null, 2),
178+
);
179+
180+
const payerRequestDataAfterDelegateConfirmed = await waitForConfirmation(
181+
payerRequestDataAfterDelegate,
182+
);
183+
console.log(
184+
"payerRequestDataAfterDelegateConfirmed: " +
185+
JSON.stringify(payerRequestDataAfterDelegateConfirmed, null, 2),
186+
);
187+
console.log(
188+
"Observe that extensions.pn-erc20-fee-proxy-contract.values.payerDelegate is set to the payer delegate identity",
189+
);
190+
191+
const payerDelegateRequest = await payerDelegateRequestClient.fromRequestId(
192+
payeeRequestData.requestId,
193+
);
194+
195+
const payerDelegateRequestData = payerDelegateRequest.getData();
196+
197+
const payerDelegateRequestDataAfterSent =
198+
await payerDelegateRequest.declareSentPayment(
199+
payerDelegateRequestData.expectedAmount,
200+
"payment initiated from the bank",
201+
payerDelegateIdentity,
202+
);
203+
console.log(
204+
"payerDelegateRequestDataAfterSent: " +
205+
JSON.stringify(payerDelegateRequestDataAfterSent, null, 2),
206+
);
207+
208+
const payerDelegateRequestDataAfterSentConfirmed = await waitForConfirmation(
209+
payerDelegateRequestDataAfterSent,
210+
);
211+
console.log(
212+
"payerDelegateRequestDataAfterSentConfirmed: " +
213+
JSON.stringify(payerDelegateRequestDataAfterSentConfirmed, null, 2),
214+
);
215+
console.log(
216+
"Observe extensionsData contains 5 events: paymentNetwork 'create', contentData 'create', paymentNetwork 'addDelegate' x2, and paymentNetwork 'declareSentPayment'",
217+
);
218+
219+
const payeeDelegateRequest = await payeeDelegateRequestClient.fromRequestId(
220+
payeeRequestData.requestId,
221+
);
222+
223+
const payeeDelegateRequestData = payeeDelegateRequest.getData();
224+
225+
const payeeDelegateRequestDataAfterReceived =
226+
await payeeDelegateRequest.declareReceivedPayment(
227+
payeeDelegateRequestData.expectedAmount,
228+
"payment received from the bank",
229+
payeeDelegateIdentity,
230+
);
231+
232+
const payeeDelegateRequestDataAfterReceivedConfirmed =
233+
await waitForConfirmation(payeeDelegateRequestDataAfterReceived);
234+
console.log(
235+
"payeeDelegateRequestDataAfterReceivedConfirmed: " +
236+
JSON.stringify(payeeDelegateRequestDataAfterReceivedConfirmed, null, 2),
237+
);
238+
console.log(
239+
"Observe extensionsData contains 6 events: paymentNetwork 'create', contentData 'create', paymentNetwork 'addDelegate' x2, paymentNetwork 'declareSentPayment', and paymentNetwork 'declareReceivedPayment'",
240+
);
241+
242+
console.log(
243+
"Request balance: " +
244+
payeeDelegateRequestDataAfterReceivedConfirmed.balance.balance,
245+
);
246+
console.log(
247+
`Observe that the balance is ${requestCreateParameters.requestInfo.expectedAmount}`,
248+
);
249+
console.log(
250+
"Request balance events: " +
251+
JSON.stringify(
252+
payeeDelegateRequestDataAfterReceivedConfirmed.balance.events,
253+
null,
254+
2,
255+
),
256+
);
257+
console.log(
258+
`Observe that the balance event note is "payment received from the bank"`,
259+
);
260+
})();

0 commit comments

Comments
 (0)