@tanakayuto/intmax402-express 0.3.1 → 0.3.2

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.
@@ -18,9 +18,19 @@ function intmax402(config) {
18
18
  return async (req, res, next) => {
19
19
  try {
20
20
  // Wait for payment verifier initialization if in progress
21
- if (initPromise) {
22
- await initPromise;
23
- initPromise = null;
21
+ try {
22
+ if (initPromise) {
23
+ await initPromise;
24
+ initPromise = null;
25
+ }
26
+ }
27
+ catch (e) {
28
+ res.status(503).json({
29
+ error: 'Payment verifier temporarily unavailable',
30
+ hint: 'INTMAX network may be experiencing issues. Please try again later.',
31
+ protocol: 'INTMAX402',
32
+ });
33
+ return;
24
34
  }
25
35
  const authHeader = req.headers.authorization;
26
36
  if (!authHeader) {
@@ -40,8 +40,16 @@ async function initPaymentVerifier(config) {
40
40
  l1_rpc_url: config.l1_rpc_url,
41
41
  loggerLevel: "warn",
42
42
  });
43
- loginPromise = client.login().then(() => {
43
+ loginPromise = client
44
+ .login()
45
+ .then(() => {
44
46
  loginPromise = null;
47
+ })
48
+ .catch((err) => {
49
+ console.warn("[intmax402] INTMAX network login failed — payment verifier unavailable:", err instanceof Error ? err.message : String(err));
50
+ client = null;
51
+ loginPromise = null;
52
+ throw err;
45
53
  });
46
54
  await loginPromise;
47
55
  }
@@ -52,7 +60,10 @@ function getPaymentVerifierAddress() {
52
60
  }
53
61
  async function verifyPayment(txHash, expectedAmount, serverAddress, tokenIndex) {
54
62
  if (!client || !client.isLoggedIn) {
55
- return { valid: false, error: "Payment verifier not initialized" };
63
+ return {
64
+ valid: false,
65
+ error: "Payment verifier temporarily unavailable. INTMAX network may be down.",
66
+ };
56
67
  }
57
68
  // Replay prevention: check if txHash was already used (or pending)
58
69
  cleanupExpiredHashes();
@@ -71,7 +82,25 @@ async function verifyPayment(txHash, expectedAmount, serverAddress, tokenIndex)
71
82
  transfers = transfers.concat(response2.items);
72
83
  }
73
84
  // Find matching transaction by digest
74
- const match = transfers.find((tx) => tx.digest === txHash);
85
+ let match = transfers.find((tx) => tx.digest === txHash);
86
+ // Polling retry: if not found, retry up to 3 times with 5s delay
87
+ // (transfer may not be reflected immediately after submission)
88
+ if (!match) {
89
+ for (let retry = 0; retry < 3; retry++) {
90
+ await new Promise((r) => setTimeout(r, 5000));
91
+ const retryResponse = await client.fetchTransfers({ cursor: null, limit: 100 });
92
+ match = retryResponse.items.find((tx) => tx.digest === txHash);
93
+ if (match)
94
+ break;
95
+ // Also check next page on retry if needed
96
+ if (!match && retryResponse.pagination?.has_more && retryResponse.pagination?.next_cursor != null) {
97
+ const retryResponse2 = await client.fetchTransfers({ cursor: retryResponse.pagination.next_cursor, limit: 100 });
98
+ match = retryResponse2.items.find((tx) => tx.digest === txHash);
99
+ if (match)
100
+ break;
101
+ }
102
+ }
103
+ }
75
104
  if (!match) {
76
105
  // Fix 1: Rollback on validation failure
77
106
  usedTxHashes.delete(txHash);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanakayuto/intmax402-express",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {