@powerhousedao/contributor-billing 0.1.15 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editors/invoice/ingestPDF.js +1 -1
- package/dist/editors/invoice/invoiceToGnosis.d.ts.map +1 -1
- package/dist/editors/invoice/invoiceToGnosis.js +13 -3
- package/dist/editors/invoice/requestFinance.js +2 -2
- package/dist/editors/invoice/uploadPdfChunked.js +1 -1
- package/dist/scripts/invoice/gnosisTransactionBuilder.d.ts.map +1 -1
- package/dist/scripts/invoice/gnosisTransactionBuilder.js +34 -5
- package/dist/style.css +30 -26
- package/dist/subgraphs/invoice/customResolvers.d.ts +1 -9
- package/dist/subgraphs/invoice/customResolvers.d.ts.map +1 -1
- package/dist/subgraphs/invoice/customResolvers.js +51 -23
- package/package.json +4 -3
|
@@ -7,7 +7,7 @@ import { getCountryCodeFromName } from "./utils/utils.js";
|
|
|
7
7
|
import { LoaderCircle } from "lucide-react";
|
|
8
8
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
9
9
|
if (!window.document.baseURI.includes("localhost")) {
|
|
10
|
-
GRAPHQL_URL = "https://
|
|
10
|
+
GRAPHQL_URL = "https://switchboard-staging.powerhouse.xyz/graphql/invoice";
|
|
11
11
|
}
|
|
12
12
|
export async function loadPDFFile({ file, dispatch, }) {
|
|
13
13
|
if (!file)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoiceToGnosis.d.ts","sourceRoot":"","sources":["../../../editors/invoice/invoiceToGnosis.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACb,MAAM,wCAAwC,CAAC;AAQhD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;CACzC;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"invoiceToGnosis.d.ts","sourceRoot":"","sources":["../../../editors/invoice/invoiceToGnosis.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACb,MAAM,wCAAwC,CAAC;AAQhD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;CACzC;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA2RnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect } from "react";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
3
|
import { actions } from "../../document-models/invoice/index.js";
|
|
4
4
|
import { generateId } from "document-model";
|
|
5
5
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
6
|
-
if (!window.document.baseURI.includes(
|
|
7
|
-
GRAPHQL_URL =
|
|
6
|
+
if (!window.document.baseURI.includes('localhost')) {
|
|
7
|
+
GRAPHQL_URL = 'https://switchboard-staging.powerhouse.xyz/graphql/invoice';
|
|
8
8
|
}
|
|
9
9
|
const InvoiceToGnosis = ({ docState, dispatch, }) => {
|
|
10
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -12,6 +12,8 @@ const InvoiceToGnosis = ({ docState, dispatch, }) => {
|
|
|
12
12
|
const [invoiceStatusResponse, setInvoiceStatusResponse] = useState(null);
|
|
13
13
|
const [safeTxHash, setsafeTxHash] = useState(null);
|
|
14
14
|
const [safeAddress, setSafeAddress] = useState(null);
|
|
15
|
+
// Use ref to prevent race conditions from rapid clicks
|
|
16
|
+
const isProcessingRef = React.useRef(false);
|
|
15
17
|
const currency = docState.currency;
|
|
16
18
|
const chainName = docState.issuer?.paymentRouting?.wallet?.chainName || "";
|
|
17
19
|
const invoiceStatus = docState.status;
|
|
@@ -74,6 +76,12 @@ const InvoiceToGnosis = ({ docState, dispatch, }) => {
|
|
|
74
76
|
return tokenAddress;
|
|
75
77
|
}
|
|
76
78
|
const handleInvoiceToGnosis = async () => {
|
|
79
|
+
// Prevent concurrent calls using ref (faster than state update)
|
|
80
|
+
if (isProcessingRef.current) {
|
|
81
|
+
console.log("Payment request already in progress, ignoring duplicate click");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
isProcessingRef.current = true;
|
|
77
85
|
setIsLoading(true);
|
|
78
86
|
setError(null);
|
|
79
87
|
try {
|
|
@@ -138,9 +146,11 @@ const InvoiceToGnosis = ({ docState, dispatch, }) => {
|
|
|
138
146
|
}));
|
|
139
147
|
}
|
|
140
148
|
setIsLoading(false);
|
|
149
|
+
isProcessingRef.current = false;
|
|
141
150
|
}
|
|
142
151
|
catch (error) {
|
|
143
152
|
setIsLoading(false);
|
|
153
|
+
isProcessingRef.current = false;
|
|
144
154
|
console.error("Error during transfer:", error);
|
|
145
155
|
dispatch(actions.addPayment({
|
|
146
156
|
id: generateId(),
|
|
@@ -3,8 +3,8 @@ import { useState } from "react";
|
|
|
3
3
|
import { actions } from "../../document-models/invoice/index.js";
|
|
4
4
|
import { generateId } from "document-model";
|
|
5
5
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
6
|
-
if (!window.document.baseURI.includes(
|
|
7
|
-
GRAPHQL_URL =
|
|
6
|
+
if (!window.document.baseURI.includes('localhost')) {
|
|
7
|
+
GRAPHQL_URL = 'https://switchboard-staging.powerhouse.xyz/graphql/invoice';
|
|
8
8
|
}
|
|
9
9
|
const RequestFinance = ({ docState, dispatch, }) => {
|
|
10
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
let GRAPHQL_URL = 'http://localhost:4001/graphql/invoice';
|
|
9
9
|
if (!window.document.baseURI.includes('localhost')) {
|
|
10
|
-
GRAPHQL_URL =
|
|
10
|
+
GRAPHQL_URL = 'https://switchboard-staging.powerhouse.xyz/graphql/invoice';
|
|
11
11
|
}
|
|
12
12
|
export async function uploadPdfChunked(pdfData, endpoint = GRAPHQL_URL, chunkSize = 500 * 1024, // 500KB chunks
|
|
13
13
|
onProgress) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gnosisTransactionBuilder.d.ts","sourceRoot":"","sources":["../../../scripts/invoice/gnosisTransactionBuilder.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"gnosisTransactionBuilder.d.ts","sourceRoot":"","sources":["../../../scripts/invoice/gnosisTransactionBuilder.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AA6DD,iBAAe,uBAAuB,CACpC,SAAS,EAAE,MAAM,EACjB,mBAAmB,EAAE,aAAa,GAAG,aAAa,EAAE,GACnD,OAAO,CAAC,cAAc,CAAC,CA2GzB;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAA"}
|
|
@@ -28,6 +28,31 @@ const payerWallets = {
|
|
|
28
28
|
address: safeAddress, // Safe address
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Retry helper with exponential backoff for Safe API calls
|
|
33
|
+
* Handles rate limiting (429 errors) and temporary failures
|
|
34
|
+
*/
|
|
35
|
+
async function withRetry(fn, maxRetries = 3, initialDelay = 1000, operationName = "API call") {
|
|
36
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
37
|
+
try {
|
|
38
|
+
return await fn();
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const isRateLimit = error?.message?.includes('Too Many Requests') ||
|
|
42
|
+
error?.message?.includes('429') ||
|
|
43
|
+
error?.status === 429;
|
|
44
|
+
if (isRateLimit && attempt < maxRetries - 1) {
|
|
45
|
+
const waitTime = initialDelay * Math.pow(2, attempt); // Exponential backoff
|
|
46
|
+
console.log(`[${operationName}] Rate limited, retrying in ${waitTime}ms... (attempt ${attempt + 1}/${maxRetries})`);
|
|
47
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// If it's not a rate limit error, or we've exhausted retries, throw
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`${operationName}: Max retries (${maxRetries}) exceeded`);
|
|
55
|
+
}
|
|
31
56
|
// --- Implementation ---
|
|
32
57
|
async function executeTransferProposal(chainName, paymentDetailsInput) {
|
|
33
58
|
const payerWallet = payerWallets[chainName.toUpperCase()];
|
|
@@ -47,9 +72,11 @@ async function executeTransferProposal(chainName, paymentDetailsInput) {
|
|
|
47
72
|
// Safe API and Protocol Kit instances
|
|
48
73
|
// @ts-ignore - Ignoring constructor error as per requirements
|
|
49
74
|
const safeApiKit = new SafeApiKit({
|
|
50
|
-
chainId:
|
|
75
|
+
chainId: BigInt(payerWallet.chainId),
|
|
76
|
+
apiKey: process.env.SAFE_API_KEY
|
|
51
77
|
});
|
|
52
|
-
|
|
78
|
+
// Get next nonce with retry logic for rate limiting
|
|
79
|
+
const nextNonce = await withRetry(() => safeApiKit.getNextNonce(safeAddress), 3, 1000, "getNextNonce");
|
|
53
80
|
console.log("Next Nonce: ", nextNonce);
|
|
54
81
|
// @ts-ignore - Ignoring constructor error as per requirements
|
|
55
82
|
const protocolKit = await Safe.init({
|
|
@@ -89,13 +116,15 @@ async function executeTransferProposal(chainName, paymentDetailsInput) {
|
|
|
89
116
|
console.log('\n=== Signing & proposing ===');
|
|
90
117
|
const safeTxHash = await protocolKit.getTransactionHash(safeTx);
|
|
91
118
|
const signature = await protocolKit.signHash(safeTxHash);
|
|
92
|
-
await
|
|
119
|
+
const senderAddress = await signer.getAddress();
|
|
120
|
+
// Propose transaction with retry logic for rate limiting
|
|
121
|
+
await withRetry(async () => safeApiKit.proposeTransaction({
|
|
93
122
|
safeAddress: payerWallet.address,
|
|
94
123
|
safeTransactionData: safeTx.data,
|
|
95
124
|
safeTxHash,
|
|
96
|
-
senderAddress
|
|
125
|
+
senderAddress,
|
|
97
126
|
senderSignature: signature.data,
|
|
98
|
-
});
|
|
127
|
+
}), 3, 1000, "proposeTransaction");
|
|
99
128
|
return {
|
|
100
129
|
success: true,
|
|
101
130
|
txHash: safeTxHash,
|
package/dist/style.css
CHANGED
|
@@ -6488,7 +6488,7 @@ input[type="number"] {
|
|
|
6488
6488
|
}
|
|
6489
6489
|
}
|
|
6490
6490
|
}
|
|
6491
|
-
/*! tailwindcss v4.1.
|
|
6491
|
+
/*! tailwindcss v4.1.14 | MIT License | https://tailwindcss.com */
|
|
6492
6492
|
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
|
|
6493
6493
|
@layer properties;
|
|
6494
6494
|
@layer theme, base, components, utilities;
|
|
@@ -6765,6 +6765,9 @@ input[type="number"] {
|
|
|
6765
6765
|
::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
|
|
6766
6766
|
padding-block: 0;
|
|
6767
6767
|
}
|
|
6768
|
+
::-webkit-calendar-picker-indicator {
|
|
6769
|
+
line-height: 1;
|
|
6770
|
+
}
|
|
6768
6771
|
:-moz-ui-invalid {
|
|
6769
6772
|
box-shadow: none;
|
|
6770
6773
|
}
|
|
@@ -7623,7 +7626,7 @@ input[type="number"] {
|
|
|
7623
7626
|
border-radius: 100px;
|
|
7624
7627
|
}
|
|
7625
7628
|
.rounded-full {
|
|
7626
|
-
border-radius: calc(infinity * 1px);
|
|
7629
|
+
border-radius: calc(infinity * 1px) !important;
|
|
7627
7630
|
}
|
|
7628
7631
|
.rounded-lg {
|
|
7629
7632
|
border-radius: var(--radius-lg);
|
|
@@ -8451,7 +8454,7 @@ input[type="number"] {
|
|
|
8451
8454
|
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
|
8452
8455
|
}
|
|
8453
8456
|
.transition {
|
|
8454
|
-
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display,
|
|
8457
|
+
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
|
|
8455
8458
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
8456
8459
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
8457
8460
|
}
|
|
@@ -8638,7 +8641,7 @@ input[type="number"] {
|
|
|
8638
8641
|
}
|
|
8639
8642
|
.file\:rounded-full {
|
|
8640
8643
|
&::file-selector-button {
|
|
8641
|
-
border-radius: calc(infinity * 1px);
|
|
8644
|
+
border-radius: calc(infinity * 1px) !important;
|
|
8642
8645
|
}
|
|
8643
8646
|
}
|
|
8644
8647
|
.file\:border-0 {
|
|
@@ -8733,7 +8736,7 @@ input[type="number"] {
|
|
|
8733
8736
|
.before\:rounded-full {
|
|
8734
8737
|
&::before {
|
|
8735
8738
|
content: var(--tw-content);
|
|
8736
|
-
border-radius: calc(infinity * 1px);
|
|
8739
|
+
border-radius: calc(infinity * 1px) !important;
|
|
8737
8740
|
}
|
|
8738
8741
|
}
|
|
8739
8742
|
.before\:bg-blue-900 {
|
|
@@ -8854,7 +8857,7 @@ input[type="number"] {
|
|
|
8854
8857
|
.after\:rounded-full {
|
|
8855
8858
|
&::after {
|
|
8856
8859
|
content: var(--tw-content);
|
|
8857
|
-
border-radius: calc(infinity * 1px);
|
|
8860
|
+
border-radius: calc(infinity * 1px) !important;
|
|
8858
8861
|
}
|
|
8859
8862
|
}
|
|
8860
8863
|
.after\:bg-gray-300 {
|
|
@@ -8877,7 +8880,6 @@ input[type="number"] {
|
|
|
8877
8880
|
}
|
|
8878
8881
|
.after\:content-\[\'\'\] {
|
|
8879
8882
|
&::after {
|
|
8880
|
-
content: var(--tw-content);
|
|
8881
8883
|
--tw-content: '';
|
|
8882
8884
|
content: var(--tw-content);
|
|
8883
8885
|
}
|
|
@@ -10749,7 +10751,7 @@ input[type="number"] {
|
|
|
10749
10751
|
}
|
|
10750
10752
|
.\[\&_\.date-picker\\\\_\\\\_button-next\]\:rounded-full {
|
|
10751
10753
|
& .date-picker\_\_button-next {
|
|
10752
|
-
border-radius: calc(infinity * 1px);
|
|
10754
|
+
border-radius: calc(infinity * 1px) !important;
|
|
10753
10755
|
}
|
|
10754
10756
|
}
|
|
10755
10757
|
.\[\&_\.date-picker\\\\_\\\\_button-next\]\:border-2 {
|
|
@@ -10865,7 +10867,7 @@ input[type="number"] {
|
|
|
10865
10867
|
}
|
|
10866
10868
|
.\[\&_\.date-picker\\\\_\\\\_button-previous\]\:rounded-full {
|
|
10867
10869
|
& .date-picker\_\_button-previous {
|
|
10868
|
-
border-radius: calc(infinity * 1px);
|
|
10870
|
+
border-radius: calc(infinity * 1px) !important;
|
|
10869
10871
|
}
|
|
10870
10872
|
}
|
|
10871
10873
|
.\[\&_\.date-picker\\\\_\\\\_button-previous\]\:border-2 {
|
|
@@ -11037,7 +11039,7 @@ input[type="number"] {
|
|
|
11037
11039
|
}
|
|
11038
11040
|
.\[\&_\.date-picker\\\\_\\\\_day-button\]\:rounded-full {
|
|
11039
11041
|
& .date-picker\_\_day-button {
|
|
11040
|
-
border-radius: calc(infinity * 1px);
|
|
11042
|
+
border-radius: calc(infinity * 1px) !important;
|
|
11041
11043
|
}
|
|
11042
11044
|
}
|
|
11043
11045
|
.\[\&_\.date-picker\\\\_\\\\_day-button\]\:font-medium {
|
|
@@ -11387,7 +11389,7 @@ input[type="number"] {
|
|
|
11387
11389
|
}
|
|
11388
11390
|
.\[\&_\.date-picker\\\\_\\\\_today\]\:rounded-full {
|
|
11389
11391
|
& .date-picker\_\_today {
|
|
11390
|
-
border-radius: calc(infinity * 1px);
|
|
11392
|
+
border-radius: calc(infinity * 1px) !important;
|
|
11391
11393
|
}
|
|
11392
11394
|
}
|
|
11393
11395
|
.\[\&_\.date-picker\\\\_\\\\_today\]\:border-2 {
|
|
@@ -11653,7 +11655,7 @@ input[type="number"] {
|
|
|
11653
11655
|
}
|
|
11654
11656
|
.\[\&_\.radio-group\\\\_\\\\_item\]\:rounded-full {
|
|
11655
11657
|
& .radio-group\_\_item {
|
|
11656
|
-
border-radius: calc(infinity * 1px);
|
|
11658
|
+
border-radius: calc(infinity * 1px) !important;
|
|
11657
11659
|
}
|
|
11658
11660
|
}
|
|
11659
11661
|
.\[\&_\.radio-group\\\\_\\\\_item\]\:text-cyan-400 {
|
|
@@ -12545,7 +12547,7 @@ input[type="number"] {
|
|
|
12545
12547
|
.\[\&_\.date-picker\\\\_\\\\_date-footer\]\:\[\&\>button\]\:rounded-full {
|
|
12546
12548
|
& .date-picker\_\_date-footer {
|
|
12547
12549
|
&>button {
|
|
12548
|
-
border-radius: calc(infinity * 1px);
|
|
12550
|
+
border-radius: calc(infinity * 1px) !important;
|
|
12549
12551
|
}
|
|
12550
12552
|
}
|
|
12551
12553
|
}
|
|
@@ -13162,7 +13164,7 @@ input[type="number"] {
|
|
|
13162
13164
|
}
|
|
13163
13165
|
}
|
|
13164
13166
|
}
|
|
13165
|
-
/*! tailwindcss v4.1.
|
|
13167
|
+
/*! tailwindcss v4.1.14 | MIT License | https://tailwindcss.com */
|
|
13166
13168
|
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
|
|
13167
13169
|
@layer properties;
|
|
13168
13170
|
@layer theme, base, components, utilities;
|
|
@@ -13439,6 +13441,9 @@ input[type="number"] {
|
|
|
13439
13441
|
::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
|
|
13440
13442
|
padding-block: 0;
|
|
13441
13443
|
}
|
|
13444
|
+
::-webkit-calendar-picker-indicator {
|
|
13445
|
+
line-height: 1;
|
|
13446
|
+
}
|
|
13442
13447
|
:-moz-ui-invalid {
|
|
13443
13448
|
box-shadow: none;
|
|
13444
13449
|
}
|
|
@@ -14297,7 +14302,7 @@ input[type="number"] {
|
|
|
14297
14302
|
border-radius: 100px;
|
|
14298
14303
|
}
|
|
14299
14304
|
.rounded-full {
|
|
14300
|
-
border-radius: calc(infinity * 1px);
|
|
14305
|
+
border-radius: calc(infinity * 1px) !important;
|
|
14301
14306
|
}
|
|
14302
14307
|
.rounded-lg {
|
|
14303
14308
|
border-radius: var(--radius-lg);
|
|
@@ -15125,7 +15130,7 @@ input[type="number"] {
|
|
|
15125
15130
|
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
|
15126
15131
|
}
|
|
15127
15132
|
.transition {
|
|
15128
|
-
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display,
|
|
15133
|
+
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
|
|
15129
15134
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
15130
15135
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
15131
15136
|
}
|
|
@@ -15312,7 +15317,7 @@ input[type="number"] {
|
|
|
15312
15317
|
}
|
|
15313
15318
|
.file\:rounded-full {
|
|
15314
15319
|
&::file-selector-button {
|
|
15315
|
-
border-radius: calc(infinity * 1px);
|
|
15320
|
+
border-radius: calc(infinity * 1px) !important;
|
|
15316
15321
|
}
|
|
15317
15322
|
}
|
|
15318
15323
|
.file\:border-0 {
|
|
@@ -15407,7 +15412,7 @@ input[type="number"] {
|
|
|
15407
15412
|
.before\:rounded-full {
|
|
15408
15413
|
&::before {
|
|
15409
15414
|
content: var(--tw-content);
|
|
15410
|
-
border-radius: calc(infinity * 1px);
|
|
15415
|
+
border-radius: calc(infinity * 1px) !important;
|
|
15411
15416
|
}
|
|
15412
15417
|
}
|
|
15413
15418
|
.before\:bg-blue-900 {
|
|
@@ -15528,7 +15533,7 @@ input[type="number"] {
|
|
|
15528
15533
|
.after\:rounded-full {
|
|
15529
15534
|
&::after {
|
|
15530
15535
|
content: var(--tw-content);
|
|
15531
|
-
border-radius: calc(infinity * 1px);
|
|
15536
|
+
border-radius: calc(infinity * 1px) !important;
|
|
15532
15537
|
}
|
|
15533
15538
|
}
|
|
15534
15539
|
.after\:bg-gray-300 {
|
|
@@ -15551,7 +15556,6 @@ input[type="number"] {
|
|
|
15551
15556
|
}
|
|
15552
15557
|
.after\:content-\[\'\'\] {
|
|
15553
15558
|
&::after {
|
|
15554
|
-
content: var(--tw-content);
|
|
15555
15559
|
--tw-content: '';
|
|
15556
15560
|
content: var(--tw-content);
|
|
15557
15561
|
}
|
|
@@ -17423,7 +17427,7 @@ input[type="number"] {
|
|
|
17423
17427
|
}
|
|
17424
17428
|
.\[\&_\.date-picker\\\\_\\\\_button-next\]\:rounded-full {
|
|
17425
17429
|
& .date-picker\_\_button-next {
|
|
17426
|
-
border-radius: calc(infinity * 1px);
|
|
17430
|
+
border-radius: calc(infinity * 1px) !important;
|
|
17427
17431
|
}
|
|
17428
17432
|
}
|
|
17429
17433
|
.\[\&_\.date-picker\\\\_\\\\_button-next\]\:border-2 {
|
|
@@ -17539,7 +17543,7 @@ input[type="number"] {
|
|
|
17539
17543
|
}
|
|
17540
17544
|
.\[\&_\.date-picker\\\\_\\\\_button-previous\]\:rounded-full {
|
|
17541
17545
|
& .date-picker\_\_button-previous {
|
|
17542
|
-
border-radius: calc(infinity * 1px);
|
|
17546
|
+
border-radius: calc(infinity * 1px) !important;
|
|
17543
17547
|
}
|
|
17544
17548
|
}
|
|
17545
17549
|
.\[\&_\.date-picker\\\\_\\\\_button-previous\]\:border-2 {
|
|
@@ -17711,7 +17715,7 @@ input[type="number"] {
|
|
|
17711
17715
|
}
|
|
17712
17716
|
.\[\&_\.date-picker\\\\_\\\\_day-button\]\:rounded-full {
|
|
17713
17717
|
& .date-picker\_\_day-button {
|
|
17714
|
-
border-radius: calc(infinity * 1px);
|
|
17718
|
+
border-radius: calc(infinity * 1px) !important;
|
|
17715
17719
|
}
|
|
17716
17720
|
}
|
|
17717
17721
|
.\[\&_\.date-picker\\\\_\\\\_day-button\]\:font-medium {
|
|
@@ -18061,7 +18065,7 @@ input[type="number"] {
|
|
|
18061
18065
|
}
|
|
18062
18066
|
.\[\&_\.date-picker\\\\_\\\\_today\]\:rounded-full {
|
|
18063
18067
|
& .date-picker\_\_today {
|
|
18064
|
-
border-radius: calc(infinity * 1px);
|
|
18068
|
+
border-radius: calc(infinity * 1px) !important;
|
|
18065
18069
|
}
|
|
18066
18070
|
}
|
|
18067
18071
|
.\[\&_\.date-picker\\\\_\\\\_today\]\:border-2 {
|
|
@@ -18327,7 +18331,7 @@ input[type="number"] {
|
|
|
18327
18331
|
}
|
|
18328
18332
|
.\[\&_\.radio-group\\\\_\\\\_item\]\:rounded-full {
|
|
18329
18333
|
& .radio-group\_\_item {
|
|
18330
|
-
border-radius: calc(infinity * 1px);
|
|
18334
|
+
border-radius: calc(infinity * 1px) !important;
|
|
18331
18335
|
}
|
|
18332
18336
|
}
|
|
18333
18337
|
.\[\&_\.radio-group\\\\_\\\\_item\]\:text-cyan-400 {
|
|
@@ -19219,7 +19223,7 @@ input[type="number"] {
|
|
|
19219
19223
|
.\[\&_\.date-picker\\\\_\\\\_date-footer\]\:\[\&\>button\]\:rounded-full {
|
|
19220
19224
|
& .date-picker\_\_date-footer {
|
|
19221
19225
|
&>button {
|
|
19222
|
-
border-radius: calc(infinity * 1px);
|
|
19226
|
+
border-radius: calc(infinity * 1px) !important;
|
|
19223
19227
|
}
|
|
19224
19228
|
}
|
|
19225
19229
|
}
|
|
@@ -11,15 +11,7 @@ interface UploadInvoicePdfChunkArgs {
|
|
|
11
11
|
fileName: string;
|
|
12
12
|
sessionId: string;
|
|
13
13
|
}
|
|
14
|
-
export declare const Invoice_processGnosisPayment: (_: any, args: any) => Promise<
|
|
15
|
-
success: boolean;
|
|
16
|
-
data: import("../../scripts/invoice/gnosisTransactionBuilder.js").TransferResult;
|
|
17
|
-
error?: undefined;
|
|
18
|
-
} | {
|
|
19
|
-
success: boolean;
|
|
20
|
-
error: string;
|
|
21
|
-
data?: undefined;
|
|
22
|
-
}>;
|
|
14
|
+
export declare const Invoice_processGnosisPayment: (_: any, args: any) => Promise<any>;
|
|
23
15
|
export declare const Invoice_createRequestFinancePayment: (_: any, args: any) => Promise<{
|
|
24
16
|
success: boolean;
|
|
25
17
|
error: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customResolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/invoice/customResolvers.ts"],"names":[],"mappings":"AAOA,QAAA,IAAI,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,GAAG,CAAC;IACpB,SAAS,EAAE,MAAM,CAAA;CACpB,CAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"customResolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/invoice/customResolvers.ts"],"names":[],"mappings":"AAOA,QAAA,IAAI,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,GAAG,CAAC;IACpB,SAAS,EAAE,MAAM,CAAA;CACpB,CAAM,CAAC;AAQR,UAAU,yBAAyB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACrB;AAaD,eAAO,MAAM,4BAA4B,GAAU,GAAG,GAAG,EAAE,MAAM,GAAG,iBAwEnE,CAAC;AAEF,eAAO,MAAM,mCAAmC,GAAU,GAAG,GAAG,EAAE,MAAM,GAAG;;;;;;;;;;;EAkC1E,CAAA;AAED,eAAO,MAAM,6BAA6B,GAAU,GAAG,GAAG,EAAE,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;EA8E1F,CAAA;AAGD,eAAO,MAAM,UAAU,GAAI,iBAAiB,GAAG,SAE9C,CAAC;AAGF,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAG/B,eAAO,MAAM,6BAA6B,YAyBzC,CAAA;AAwCD,eAAO,MAAM,aAAa,GAAU,KAAK,GAAG,EAAE,KAAK,GAAG,iBAkJrD,CAAA"}
|
|
@@ -7,43 +7,71 @@ import * as crypto from "crypto";
|
|
|
7
7
|
let pendingTransactions = {};
|
|
8
8
|
// Add a set to track processed transaction hashes to avoid duplicate processing
|
|
9
9
|
let processedTransactions = new Set();
|
|
10
|
+
// Track in-flight payment requests to prevent concurrent processing of the same invoice
|
|
11
|
+
const inFlightPayments = new Map();
|
|
10
12
|
// Create a Map to store file chunks data
|
|
11
13
|
const fileChunksMap = new Map();
|
|
12
14
|
let reactor;
|
|
13
15
|
export const Invoice_processGnosisPayment = async (_, args) => {
|
|
14
16
|
try {
|
|
15
17
|
const { chainName, paymentDetails, invoiceNo } = args;
|
|
16
|
-
// Cast payerWallet to any to access its properties
|
|
17
18
|
console.log("Processing gnosis payment:", {
|
|
18
19
|
chainName,
|
|
19
20
|
invoiceNo,
|
|
20
21
|
paymentDetails
|
|
21
22
|
});
|
|
22
|
-
//
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// Generate a unique ID for this transaction
|
|
28
|
-
const transactionId = `gnosis-${invoiceNo}-${Date.now()}`;
|
|
29
|
-
// Store the transaction with all the details needed for matching
|
|
30
|
-
pendingTransactions[transactionId] = {
|
|
31
|
-
invoiceNo,
|
|
32
|
-
chainName,
|
|
33
|
-
paymentDetails,
|
|
34
|
-
timestamp: Date.now()
|
|
35
|
-
};
|
|
36
|
-
console.log(`Stored pending transaction ${transactionId} for invoice ${invoiceNo}`);
|
|
23
|
+
// Check if there's already a payment request in progress for this invoice
|
|
24
|
+
const paymentKey = `payment-${invoiceNo}`;
|
|
25
|
+
if (inFlightPayments.has(paymentKey)) {
|
|
26
|
+
console.log(`Payment request already in progress for invoice ${invoiceNo}, returning existing promise`);
|
|
27
|
+
return await inFlightPayments.get(paymentKey);
|
|
37
28
|
}
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
29
|
+
// Create a promise for this payment request
|
|
30
|
+
const paymentPromise = (async () => {
|
|
31
|
+
try {
|
|
32
|
+
// Import and call the executeTransferProposal function
|
|
33
|
+
const result = await executeTransferProposal(chainName, paymentDetails);
|
|
34
|
+
console.log("Token transfer result:", result);
|
|
35
|
+
// Store the transaction information for later matching with webhook
|
|
36
|
+
if (result.success && result.txHash) {
|
|
37
|
+
// Generate a unique ID for this transaction
|
|
38
|
+
const transactionId = `gnosis-${invoiceNo}-${Date.now()}`;
|
|
39
|
+
// Store the transaction with all the details needed for matching
|
|
40
|
+
pendingTransactions[transactionId] = {
|
|
41
|
+
invoiceNo,
|
|
42
|
+
chainName,
|
|
43
|
+
paymentDetails,
|
|
44
|
+
timestamp: Date.now()
|
|
45
|
+
};
|
|
46
|
+
console.log(`Stored pending transaction ${transactionId} for invoice ${invoiceNo}`);
|
|
47
|
+
}
|
|
48
|
+
// Return the result without updating the document status yet
|
|
49
|
+
// The status will be updated when the webhook confirms the transaction
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
data: result,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error("Error processing gnosis payment:", error);
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
// Remove from in-flight payments when done (success or error)
|
|
64
|
+
inFlightPayments.delete(paymentKey);
|
|
65
|
+
console.log(`Removed payment request for invoice ${invoiceNo} from in-flight tracking`);
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
// Store the promise to prevent concurrent requests
|
|
69
|
+
inFlightPayments.set(paymentKey, paymentPromise);
|
|
70
|
+
// Wait for the payment to complete
|
|
71
|
+
return await paymentPromise;
|
|
44
72
|
}
|
|
45
73
|
catch (error) {
|
|
46
|
-
console.error("Error
|
|
74
|
+
console.error("Error in Invoice_processGnosisPayment wrapper:", error);
|
|
47
75
|
return {
|
|
48
76
|
success: false,
|
|
49
77
|
error: error instanceof Error ? error.message : "Unknown error",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/contributor-billing",
|
|
3
3
|
"description": "Document models that help contributors of open organisations get paid anonymously for their work on a monthly basis.",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.17",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@powerhousedao/design-system": "^5.0.0-staging.30",
|
|
62
62
|
"@powerhousedao/document-engineering": "1.39.0",
|
|
63
63
|
"@react-pdf/renderer": "^4.3.0",
|
|
64
|
-
"@safe-global/api-kit": "^
|
|
64
|
+
"@safe-global/api-kit": "^4.0.0",
|
|
65
65
|
"@safe-global/protocol-kit": "^6.0.3",
|
|
66
66
|
"@safe-global/sdk-starter-kit": "^2.0.2",
|
|
67
67
|
"@safe-global/types-kit": "^2.0.1",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"@testing-library/react": "^16.3.0",
|
|
98
98
|
"@types/node": "^22.14.1",
|
|
99
99
|
"@types/react": "^18.3.20",
|
|
100
|
+
"@types/react-dom": "^19.2.2",
|
|
100
101
|
"@vitejs/plugin-react": "^4.4.1",
|
|
101
102
|
"document-drive": "^5.0.0-staging.30",
|
|
102
103
|
"eslint": "^9.25.0",
|
|
@@ -118,4 +119,4 @@
|
|
|
118
119
|
"react": "^18.3.1",
|
|
119
120
|
"react-dom": "^18.3.1"
|
|
120
121
|
}
|
|
121
|
-
}
|
|
122
|
+
}
|