@microcosmmoney/portal-react 3.13.9 → 3.13.10

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.
@@ -82,6 +82,9 @@ function MiningModal({ isOpen, onClose, userDetails, onSuccess }) {
82
82
  const [pollElapsedSec, setPollElapsedSec] = (0, react_1.useState)(0);
83
83
  const pollIntervalRef = (0, react_1.useRef)(null);
84
84
  const pollStartTsRef = (0, react_1.useRef)(0);
85
+ const referencePollAbortRef = (0, react_1.useRef)(false);
86
+ const referencePubkeyRef = (0, react_1.useRef)(null);
87
+ const successFiredRef = (0, react_1.useRef)(false);
85
88
  const isMobile = typeof window !== "undefined" ? (0, solana_pay_1.isMobileDevice)() : false;
86
89
  const loadStablecoinBalance = (0, react_1.useCallback)(async () => {
87
90
  if (!publicKey || !connected) {
@@ -114,8 +117,29 @@ function MiningModal({ isOpen, onClose, userDetails, onSuccess }) {
114
117
  clearInterval(pollIntervalRef.current);
115
118
  pollIntervalRef.current = null;
116
119
  }
120
+ referencePollAbortRef.current = true;
117
121
  }, []);
118
122
  (0, react_1.useEffect)(() => () => { stopStatusPolling(); }, [stopStatusPolling]);
123
+ const startReferenceWatch = (0, react_1.useCallback)(async (reference) => {
124
+ referencePollAbortRef.current = false;
125
+ try {
126
+ const connection = new web3_js_1.Connection(SOLANA_RPC, "confirmed");
127
+ while (!referencePollAbortRef.current) {
128
+ try {
129
+ const sigs = await connection.getSignaturesForAddress(reference, { limit: 1 }, "confirmed");
130
+ if (sigs.length > 0 && !sigs[0].err) {
131
+ const sig = sigs[0].signature;
132
+ setTxSignature(prev => prev || sig);
133
+ setBackendStatus(prev => (prev === "created" ? "submitted" : prev));
134
+ break;
135
+ }
136
+ }
137
+ catch { }
138
+ await new Promise(r => setTimeout(r, 1500));
139
+ }
140
+ }
141
+ catch { }
142
+ }, []);
119
143
  const startStatusPolling = (0, react_1.useCallback)((requestId) => {
120
144
  stopStatusPolling();
121
145
  pollStartTsRef.current = Date.now();
@@ -143,6 +167,10 @@ function MiningModal({ isOpen, onClose, userDetails, onSuccess }) {
143
167
  status: "completed",
144
168
  });
145
169
  setStep("success");
170
+ if (onSuccess && !successFiredRef.current) {
171
+ successFiredRef.current = true;
172
+ onSuccess();
173
+ }
146
174
  }
147
175
  else if (data.status === "failed") {
148
176
  stopStatusPolling();
@@ -198,9 +226,11 @@ function MiningModal({ isOpen, onClose, userDetails, onSuccess }) {
198
226
  });
199
227
  setSolanaPayUrl(payUrl);
200
228
  setBackendStatus("created");
229
+ referencePubkeyRef.current = reference;
201
230
  if (isMobile) {
202
231
  setStep("qrPayment");
203
232
  startStatusPolling(response.data.request_id);
233
+ startReferenceWatch(reference);
204
234
  }
205
235
  else {
206
236
  setStep("paymentMethod");
@@ -219,6 +249,8 @@ function MiningModal({ isOpen, onClose, userDetails, onSuccess }) {
219
249
  return;
220
250
  setStep("qrPayment");
221
251
  startStatusPolling(miningRequest.request_id);
252
+ if (referencePubkeyRef.current)
253
+ startReferenceWatch(referencePubkeyRef.current);
222
254
  };
223
255
  const handleSelectBrowserPayment = async () => {
224
256
  if (!connected || !publicKey) {
@@ -279,6 +311,10 @@ function MiningModal({ isOpen, onClose, userDetails, onSuccess }) {
279
311
  throw new Error(confirmResponse.error || t("errorConfirmPayment"));
280
312
  setConfirmationResult(confirmResponse.data);
281
313
  setStep("success");
314
+ if (onSuccess && !successFiredRef.current) {
315
+ successFiredRef.current = true;
316
+ onSuccess();
317
+ }
282
318
  }
283
319
  catch (err) {
284
320
  setError(err instanceof Error ? err.message : t("errorMiningFailed"));
@@ -301,8 +337,12 @@ function MiningModal({ isOpen, onClose, userDetails, onSuccess }) {
301
337
  setConfirmationResult(null);
302
338
  setSolanaPayUrl("");
303
339
  setBackendStatus("created");
304
- if (onSuccess)
340
+ referencePubkeyRef.current = null;
341
+ if (onSuccess && !successFiredRef.current) {
342
+ successFiredRef.current = true;
305
343
  onSuccess();
344
+ }
345
+ successFiredRef.current = false;
306
346
  onClose();
307
347
  }, [stopStatusPolling, onClose, onSuccess]);
308
348
  const handleClose = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microcosmmoney/portal-react",
3
- "version": "3.13.9",
3
+ "version": "3.13.10",
4
4
  "description": "Microcosm Portal UI components for React/Next.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",