@provex/react 1.11.0 → 2.0.0
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/{ProvexProvider-BAFqjyNz.d.cts → ProvexProvider-BE5MY2Zz.d.ts} +151 -73
- package/dist/{ProvexProvider-BAFqjyNz.d.ts → ProvexProvider-BG3DefVn.d.cts} +151 -73
- package/dist/{chunk-B3N7BGJD.js → chunk-RVG3ZJZK.js} +398 -214
- package/dist/chunk-RVG3ZJZK.js.map +1 -0
- package/dist/clock-BDtn-Itb.d.cts +29 -0
- package/dist/clock-BDtn-Itb.d.ts +29 -0
- package/dist/index.cjs +419 -212
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +381 -30
- package/dist/index.d.ts +381 -30
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/testing.cjs +53 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +31 -0
- package/dist/testing.d.ts +31 -0
- package/dist/testing.js +51 -0
- package/dist/testing.js.map +1 -0
- package/dist/wagmi.cjs +352 -165
- package/dist/wagmi.cjs.map +1 -1
- package/dist/wagmi.d.cts +2 -1
- package/dist/wagmi.d.ts +2 -1
- package/dist/wagmi.js +1 -1
- package/package.json +13 -6
- package/dist/chunk-B3N7BGJD.js.map +0 -1
package/dist/wagmi.cjs
CHANGED
|
@@ -11,15 +11,15 @@ var currencies = require('@provex/utils/currencies');
|
|
|
11
11
|
var tokens = require('@provex/utils/tokens');
|
|
12
12
|
var units = require('@provex/utils/units');
|
|
13
13
|
var conversionRates = require('@provex/utils/conversionRates');
|
|
14
|
-
var reputation = require('@provex/utils/reputation');
|
|
15
14
|
var contracts = require('@provex/utils/contracts');
|
|
16
15
|
var proving = require('@provex/proving');
|
|
16
|
+
var chain = require('@provex/utils/chain');
|
|
17
17
|
var utils = require('@provex/utils');
|
|
18
18
|
var deposit = require('@provex/utils/deposit');
|
|
19
19
|
var fees = require('@provex/utils/fees');
|
|
20
20
|
var abis = require('@provex/abis');
|
|
21
|
-
var chain = require('@provex/utils/chain');
|
|
22
21
|
var chains = require('viem/chains');
|
|
22
|
+
var reputation = require('@provex/utils/reputation');
|
|
23
23
|
var extensionReact = require('@provex/extension-react');
|
|
24
24
|
|
|
25
25
|
// src/wagmi/useWagmiWallet.ts
|
|
@@ -80,6 +80,15 @@ function createApiClient(apiUrl) {
|
|
|
80
80
|
})
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
|
+
|
|
84
|
+
// src/lib/clock.ts
|
|
85
|
+
var systemClock = Object.freeze({
|
|
86
|
+
now: () => Date.now(),
|
|
87
|
+
setTimeout: (callback, delayMs) => globalThis.setTimeout(callback, delayMs),
|
|
88
|
+
clearTimeout: (handle) => globalThis.clearTimeout(handle),
|
|
89
|
+
setInterval: (callback, intervalMs) => globalThis.setInterval(callback, intervalMs),
|
|
90
|
+
clearInterval: (handle) => globalThis.clearInterval(handle)
|
|
91
|
+
});
|
|
83
92
|
var ProvexContext = react.createContext(null);
|
|
84
93
|
var defaultQueryClient = new reactQuery.QueryClient({
|
|
85
94
|
defaultOptions: {
|
|
@@ -96,22 +105,23 @@ function ProvexProvider({
|
|
|
96
105
|
publicClient: publicClient2,
|
|
97
106
|
publicClients,
|
|
98
107
|
wallet,
|
|
108
|
+
clock = systemClock,
|
|
99
109
|
children
|
|
100
110
|
}) {
|
|
101
111
|
const resolvedQueryClient = queryClient ?? defaultQueryClient;
|
|
102
112
|
const contextValue = react.useMemo(() => {
|
|
103
113
|
const apiClient = createApiClient(config.apiUrl);
|
|
104
114
|
const chainId = config.chain.id;
|
|
105
|
-
const
|
|
106
|
-
const resolved = { ...
|
|
115
|
+
const base = publicClients ?? {};
|
|
116
|
+
const resolved = { ...base };
|
|
107
117
|
if (publicClient2 && !resolved[chainId]) {
|
|
108
118
|
resolved[chainId] = publicClient2;
|
|
109
119
|
}
|
|
110
120
|
if (!resolved[chainId]) {
|
|
111
121
|
resolved[chainId] = viem.createPublicClient({ chain: config.chain, transport: viem.http() });
|
|
112
122
|
}
|
|
113
|
-
return { config, indexer, apiClient, publicClients: resolved, wallet };
|
|
114
|
-
}, [config, indexer, publicClient2, publicClients, wallet]);
|
|
123
|
+
return { config, indexer, apiClient, publicClients: resolved, wallet, clock };
|
|
124
|
+
}, [config, indexer, publicClient2, publicClients, wallet, clock]);
|
|
115
125
|
return /* @__PURE__ */ jsxRuntime.jsx(ProvexContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: resolvedQueryClient, children }) });
|
|
116
126
|
}
|
|
117
127
|
function useProvex() {
|
|
@@ -130,6 +140,9 @@ function useOptionalProvexPublicClient(chainId) {
|
|
|
130
140
|
const target = chainId ?? ctx.config.chain.id;
|
|
131
141
|
return ctx.publicClients[target];
|
|
132
142
|
}
|
|
143
|
+
function useClock() {
|
|
144
|
+
return useOptionalProvex()?.clock ?? systemClock;
|
|
145
|
+
}
|
|
133
146
|
function WagmiProvexProvider(props) {
|
|
134
147
|
const publicClients = useWagmiPublicClients();
|
|
135
148
|
const wallet = useWagmiWallet() ?? void 0;
|
|
@@ -267,25 +280,29 @@ var getTransactionGasInputs = async (chainId) => {
|
|
|
267
280
|
// src/lib/updates.ts
|
|
268
281
|
var POLL_INTERVAL_MS = 1e3;
|
|
269
282
|
var SLOW_SYNC_THRESHOLD_MS = 15e3;
|
|
283
|
+
var sleep = (clock, delayMs) => new Promise((resolve) => {
|
|
284
|
+
clock.setTimeout(resolve, delayMs);
|
|
285
|
+
});
|
|
270
286
|
var checkTransactionIndexed = async ({
|
|
271
287
|
queryTransaction,
|
|
272
288
|
hash,
|
|
273
289
|
onSuccess,
|
|
274
290
|
onSlowSync,
|
|
275
|
-
slowSyncThresholdMs = SLOW_SYNC_THRESHOLD_MS
|
|
291
|
+
slowSyncThresholdMs = SLOW_SYNC_THRESHOLD_MS,
|
|
292
|
+
clock = systemClock
|
|
276
293
|
}) => {
|
|
277
|
-
const startTime =
|
|
294
|
+
const startTime = clock.now();
|
|
278
295
|
let slowSyncFired = false;
|
|
279
296
|
while (true) {
|
|
280
297
|
const result = await queryTransaction(hash);
|
|
281
298
|
if (result) {
|
|
282
299
|
break;
|
|
283
300
|
}
|
|
284
|
-
if (!slowSyncFired && onSlowSync &&
|
|
301
|
+
if (!slowSyncFired && onSlowSync && clock.now() - startTime > slowSyncThresholdMs) {
|
|
285
302
|
slowSyncFired = true;
|
|
286
303
|
onSlowSync();
|
|
287
304
|
}
|
|
288
|
-
await
|
|
305
|
+
await sleep(clock, POLL_INTERVAL_MS);
|
|
289
306
|
}
|
|
290
307
|
onSuccess?.();
|
|
291
308
|
};
|
|
@@ -630,7 +647,7 @@ var ProveXClient = class {
|
|
|
630
647
|
* Handles all encoding internally:
|
|
631
648
|
* 1. Registers payee details with the API (so buyers can discover them)
|
|
632
649
|
* 2. Hashes provider keys and currency codes to bytes32
|
|
633
|
-
* 3.
|
|
650
|
+
* 3. Collapses bank-level keys to their rail (e.g., 'zelle-chase' → 'zelle'); Zelle is one rail
|
|
634
651
|
* 4. Encodes gating service witness signers
|
|
635
652
|
* 5. Submits the on-chain transaction
|
|
636
653
|
*
|
|
@@ -920,43 +937,6 @@ var ProveXClient = class {
|
|
|
920
937
|
});
|
|
921
938
|
return res.responseObject ?? null;
|
|
922
939
|
}
|
|
923
|
-
/**
|
|
924
|
-
* Submit zkTLS proofs and get a signed attestation for fulfillIntent.
|
|
925
|
-
* This is the proof verification step — after the buyer makes payment and
|
|
926
|
-
* generates proofs via the browser extension.
|
|
927
|
-
*/
|
|
928
|
-
async getAttestation(params) {
|
|
929
|
-
const endpoint = `/api/v0/attestation/verify/${params.platform}/${params.actionType}`;
|
|
930
|
-
const proof = params.proofs.length === 1 ? params.proofs[0] : params.proofs;
|
|
931
|
-
const res = await fetch(`${this.apiUrl}${endpoint}`, {
|
|
932
|
-
method: "POST",
|
|
933
|
-
headers: { "Content-Type": "application/json" },
|
|
934
|
-
body: JSON.stringify({
|
|
935
|
-
proofType: "reclaim",
|
|
936
|
-
proof: JSON.stringify(proof),
|
|
937
|
-
chainId: params.chainId,
|
|
938
|
-
verifyingContract: params.verifyingContract,
|
|
939
|
-
intent: params.intent
|
|
940
|
-
})
|
|
941
|
-
});
|
|
942
|
-
if (!res.ok) {
|
|
943
|
-
let errorMessage = `Attestation error: ${res.status}`;
|
|
944
|
-
try {
|
|
945
|
-
const errorJson = await res.json();
|
|
946
|
-
if (errorJson.details?.message) errorMessage = errorJson.details.message;
|
|
947
|
-
else if (errorJson.message) errorMessage = errorJson.message;
|
|
948
|
-
else if (errorJson.error) errorMessage = errorJson.error;
|
|
949
|
-
} catch {
|
|
950
|
-
}
|
|
951
|
-
return {
|
|
952
|
-
success: false,
|
|
953
|
-
message: errorMessage,
|
|
954
|
-
statusCode: res.status,
|
|
955
|
-
responseObject: {}
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
return await res.json();
|
|
959
|
-
}
|
|
960
940
|
/** Make a POST request to the API. */
|
|
961
941
|
async apiPost(path, body) {
|
|
962
942
|
const res = await fetch(`${this.apiUrl}${path}`, {
|
|
@@ -1056,6 +1036,11 @@ function createProveXClient(config) {
|
|
|
1056
1036
|
}
|
|
1057
1037
|
|
|
1058
1038
|
// src/hooks/useSignalIntent.ts
|
|
1039
|
+
var DEFAULT_SIGNAL_INTENT_MESSAGES = {
|
|
1040
|
+
clientOrDepositUnavailable: "Client or deposit not available",
|
|
1041
|
+
noEscrowAddress: "No escrow address found",
|
|
1042
|
+
success: "Intent signaled successfully"
|
|
1043
|
+
};
|
|
1059
1044
|
var ERROR_PATTERNS = [
|
|
1060
1045
|
{ pattern: /user rejected|user denied|rejected the request|user cancelled|user canceled/i, message: "Transaction was cancelled." },
|
|
1061
1046
|
{ pattern: /InsufficientDepositLiquidity|0xc3df48f3/i, message: "This deposit no longer has enough available liquidity. Please try a smaller amount or a different deposit." },
|
|
@@ -1070,28 +1055,48 @@ function getUserFriendlyErrorMessage(error) {
|
|
|
1070
1055
|
}
|
|
1071
1056
|
return "Something went wrong. Please try again.";
|
|
1072
1057
|
}
|
|
1058
|
+
function isClientRejection(error) {
|
|
1059
|
+
return error instanceof ProveXError && error.isRejection;
|
|
1060
|
+
}
|
|
1061
|
+
var LOADING_STATUSES = /* @__PURE__ */ new Set([
|
|
1062
|
+
"loading_payee",
|
|
1063
|
+
"loading_intent",
|
|
1064
|
+
"prompt_wallet_confirm",
|
|
1065
|
+
"writing_intent"
|
|
1066
|
+
]);
|
|
1073
1067
|
function useSignalIntent({
|
|
1074
1068
|
wallet,
|
|
1069
|
+
chainId,
|
|
1070
|
+
indexer,
|
|
1071
|
+
apiUrl,
|
|
1075
1072
|
onSuccess,
|
|
1076
1073
|
onFailure,
|
|
1077
1074
|
deposit,
|
|
1078
|
-
refetchDeposits
|
|
1075
|
+
refetchDeposits,
|
|
1076
|
+
beginTransaction,
|
|
1077
|
+
isRejection = isClientRejection,
|
|
1078
|
+
formatError = getUserFriendlyErrorMessage,
|
|
1079
|
+
messages
|
|
1079
1080
|
}) {
|
|
1080
1081
|
const provex = useOptionalProvex();
|
|
1081
1082
|
const [status, setStatus] = react.useState("input");
|
|
1082
1083
|
const [message, setMessage] = react.useState(null);
|
|
1084
|
+
const copy = { ...DEFAULT_SIGNAL_INTENT_MESSAGES, ...messages };
|
|
1085
|
+
const chain$1 = (chainId === void 0 ? void 0 : chain.chainIdToChain.get(chainId)) ?? provex?.config.chain;
|
|
1086
|
+
const resolvedIndexer = indexer ?? provex?.indexer;
|
|
1087
|
+
const resolvedApiUrl = apiUrl ?? provex?.config.apiUrl;
|
|
1088
|
+
const escrow = deposit?.escrow ?? void 0;
|
|
1083
1089
|
const client = react.useMemo(() => {
|
|
1084
|
-
if (!
|
|
1090
|
+
if (!chain$1 || !wallet || !resolvedIndexer || resolvedApiUrl === void 0) return null;
|
|
1085
1091
|
return createProveXClient({
|
|
1086
|
-
chain:
|
|
1087
|
-
apiUrl: provex.config.apiUrl,
|
|
1092
|
+
chain: chain$1,
|
|
1088
1093
|
wallet,
|
|
1089
|
-
indexer:
|
|
1094
|
+
indexer: resolvedIndexer,
|
|
1095
|
+
apiUrl: resolvedApiUrl,
|
|
1096
|
+
escrowAddress: escrow
|
|
1090
1097
|
});
|
|
1091
|
-
}, [
|
|
1092
|
-
const isLoading =
|
|
1093
|
-
return status === "loading_payee" || status === "loading_intent" || status === "prompt_wallet_confirm" || status === "writing_intent";
|
|
1094
|
-
}, [status]);
|
|
1098
|
+
}, [chain$1, wallet, resolvedIndexer, resolvedApiUrl, escrow]);
|
|
1099
|
+
const isLoading = LOADING_STATUSES.has(status);
|
|
1095
1100
|
const startOrder = react.useCallback(async ({
|
|
1096
1101
|
paymentMethod,
|
|
1097
1102
|
depositId,
|
|
@@ -1103,42 +1108,48 @@ function useSignalIntent({
|
|
|
1103
1108
|
}) => {
|
|
1104
1109
|
if (!client || !deposit) {
|
|
1105
1110
|
setStatus("error");
|
|
1106
|
-
setMessage(
|
|
1111
|
+
setMessage(copy.clientOrDepositUnavailable);
|
|
1107
1112
|
return;
|
|
1108
1113
|
}
|
|
1109
|
-
const
|
|
1110
|
-
if (!
|
|
1114
|
+
const depositEscrow = deposit.escrow;
|
|
1115
|
+
if (!depositEscrow) {
|
|
1111
1116
|
setStatus("error");
|
|
1112
|
-
setMessage(
|
|
1117
|
+
setMessage(copy.noEscrowAddress);
|
|
1113
1118
|
return;
|
|
1114
1119
|
}
|
|
1120
|
+
const transaction = beginTransaction ? await beginTransaction() : void 0;
|
|
1121
|
+
if (transaction === null) return;
|
|
1115
1122
|
setStatus("loading_intent");
|
|
1116
1123
|
try {
|
|
1117
1124
|
const result = await client.signalIntent({
|
|
1118
|
-
deposit: { escrow, localId: deposit.localId ?? depositId },
|
|
1125
|
+
deposit: { escrow: depositEscrow, localId: deposit.localId ?? depositId },
|
|
1119
1126
|
paymentMethod,
|
|
1120
1127
|
tokenAmount,
|
|
1121
1128
|
toAddress,
|
|
1122
1129
|
fiatCurrencyCode,
|
|
1123
1130
|
conversionRate,
|
|
1124
|
-
subProvider
|
|
1131
|
+
subProvider,
|
|
1132
|
+
onAwaitingSignature: () => transaction?.awaitingSignature(),
|
|
1133
|
+
onTransactionHash: (hash) => transaction?.attach(hash)
|
|
1125
1134
|
});
|
|
1126
1135
|
setStatus("success");
|
|
1127
|
-
setMessage(
|
|
1136
|
+
setMessage(copy.success);
|
|
1128
1137
|
onSuccess(result.intentHash);
|
|
1129
1138
|
} catch (error) {
|
|
1130
|
-
if (error
|
|
1139
|
+
if (isRejection(error)) {
|
|
1140
|
+
transaction?.failed(error);
|
|
1131
1141
|
setStatus("input");
|
|
1132
1142
|
setMessage(null);
|
|
1133
1143
|
return;
|
|
1134
1144
|
}
|
|
1135
1145
|
console.error("Failed to signal intent", error);
|
|
1146
|
+
transaction?.failed(error);
|
|
1136
1147
|
setStatus("error");
|
|
1137
|
-
setMessage(
|
|
1148
|
+
setMessage(formatError(error));
|
|
1138
1149
|
refetchDeposits?.();
|
|
1139
1150
|
onFailure?.();
|
|
1140
1151
|
}
|
|
1141
|
-
}, [client, deposit, onSuccess, onFailure, refetchDeposits]);
|
|
1152
|
+
}, [client, deposit, beginTransaction, isRejection, formatError, onSuccess, onFailure, refetchDeposits, copy.clientOrDepositUnavailable, copy.noEscrowAddress, copy.success]);
|
|
1142
1153
|
return {
|
|
1143
1154
|
startOrder,
|
|
1144
1155
|
status,
|
|
@@ -1146,93 +1157,167 @@ function useSignalIntent({
|
|
|
1146
1157
|
isLoading
|
|
1147
1158
|
};
|
|
1148
1159
|
}
|
|
1149
|
-
function
|
|
1150
|
-
|
|
1151
|
-
|
|
1160
|
+
function filteringTierFor(options) {
|
|
1161
|
+
if (options.vipStatus === "unknown") return null;
|
|
1162
|
+
if (options.vipStatus === "vip") return payment.tiers.PRESIDENT;
|
|
1163
|
+
return options.tier;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// src/hooks/useUserReputation.ts
|
|
1167
|
+
function computeUserReputation({
|
|
1168
|
+
stats,
|
|
1169
|
+
pulseTimestamp,
|
|
1170
|
+
now = () => /* @__PURE__ */ new Date()
|
|
1152
1171
|
}) {
|
|
1153
|
-
|
|
1154
|
-
const
|
|
1155
|
-
const
|
|
1156
|
-
const
|
|
1157
|
-
|
|
1172
|
+
if (!stats) return reputation.DEFAULT_REPUTATION;
|
|
1173
|
+
const makerVolume = stats.fulfilledMakerVolume ?? 0n;
|
|
1174
|
+
const makerCount = stats.fulfilledMakerCount ?? 0;
|
|
1175
|
+
const combinedVolume = stats.fulfilledVolume + makerVolume;
|
|
1176
|
+
const combinedFulfilledCount = stats.fulfilledCount + makerCount;
|
|
1177
|
+
let tier = reputation.getTierFromVolume(combinedVolume);
|
|
1178
|
+
const lockScore = stats.lateCancellations * 50;
|
|
1179
|
+
const dilutedLockScore = combinedFulfilledCount > 0 ? lockScore / (1 + combinedFulfilledCount * 0.1) : lockScore;
|
|
1180
|
+
let tierPenalty = 0;
|
|
1181
|
+
if (dilutedLockScore >= 1e3) tierPenalty = 4;
|
|
1182
|
+
else if (dilutedLockScore >= 500) tierPenalty = 3;
|
|
1183
|
+
else if (dilutedLockScore >= 200) tierPenalty = 2;
|
|
1184
|
+
else if (dilutedLockScore >= 50) tierPenalty = 1;
|
|
1185
|
+
if (tierPenalty > 0) {
|
|
1186
|
+
const currentTierIndex = reputation.TIER_ORDER.indexOf(tier);
|
|
1187
|
+
const newTierIndex = Math.max(0, currentTierIndex - tierPenalty);
|
|
1188
|
+
tier = reputation.TIER_ORDER[newTierIndex] ?? "peasant";
|
|
1189
|
+
}
|
|
1190
|
+
const cooldownHours = reputation.TAKER_TIERS[tier].cooldownHours;
|
|
1191
|
+
let cooldownEndsAt = null;
|
|
1192
|
+
let isOnCooldown = false;
|
|
1193
|
+
if (cooldownHours > 0 && pulseTimestamp !== null && pulseTimestamp !== void 0) {
|
|
1194
|
+
const lastSignaledTime = Number(pulseTimestamp) * 1e3;
|
|
1195
|
+
const cooldownMs = cooldownHours * 60 * 60 * 1e3;
|
|
1196
|
+
cooldownEndsAt = new Date(lastSignaledTime + cooldownMs);
|
|
1197
|
+
isOnCooldown = cooldownEndsAt > now();
|
|
1198
|
+
}
|
|
1199
|
+
return {
|
|
1200
|
+
tier,
|
|
1201
|
+
fulfilledVolume: combinedVolume,
|
|
1202
|
+
lockScore: dilutedLockScore,
|
|
1203
|
+
cooldownEndsAt,
|
|
1204
|
+
isOnCooldown
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
var useIndexerReputationSource = ({ address }) => {
|
|
1208
|
+
const provex = useOptionalProvex();
|
|
1209
|
+
if (!provex) {
|
|
1210
|
+
throw new Error("useUserReputation needs a <ProvexProvider> or a `source` option");
|
|
1211
|
+
}
|
|
1212
|
+
const { indexer } = provex;
|
|
1213
|
+
const query = reactQuery.useQuery({
|
|
1214
|
+
queryKey: ["provex", "reputation", address, chains.pulsechain.id],
|
|
1158
1215
|
queryFn: async () => {
|
|
1159
1216
|
if (!address) return null;
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1217
|
+
const data = await indexer.getUserReputation({ address, chainId: chains.pulsechain.id });
|
|
1218
|
+
return {
|
|
1219
|
+
fulfilledVolume: data.fulfilledVolume,
|
|
1220
|
+
fulfilledCount: data.fulfilledCount,
|
|
1221
|
+
lateCancellations: data.lateCancellations,
|
|
1222
|
+
lastSignaledAt: data.lastSignaledAt[chains.pulsechain.id] ?? null
|
|
1223
|
+
};
|
|
1164
1224
|
},
|
|
1165
1225
|
enabled: !!address,
|
|
1166
1226
|
staleTime: 6e4,
|
|
1167
1227
|
refetchInterval: 12e4
|
|
1168
1228
|
});
|
|
1229
|
+
const refetch = react.useCallback(() => query.refetch(), [query]);
|
|
1230
|
+
const row = query.data ?? null;
|
|
1231
|
+
return {
|
|
1232
|
+
stats: row,
|
|
1233
|
+
lastSignaledTimestamp: row ? row.lastSignaledAt : null,
|
|
1234
|
+
isLoading: query.isLoading,
|
|
1235
|
+
error: query.error,
|
|
1236
|
+
refetch
|
|
1237
|
+
};
|
|
1238
|
+
};
|
|
1239
|
+
function useUserReputation({
|
|
1240
|
+
address,
|
|
1241
|
+
source = useIndexerReputationSource,
|
|
1242
|
+
vipStatus = "normal",
|
|
1243
|
+
disabled
|
|
1244
|
+
}) {
|
|
1245
|
+
const provex = useOptionalProvex();
|
|
1246
|
+
const isDisabled = disabled ?? provex?.config.reputationDisabled ?? false;
|
|
1247
|
+
const { stats, lastSignaledTimestamp, isLoading: sourceLoading, error, refetch: refetchSource } = source({ address });
|
|
1248
|
+
const canBypassCooldown = vipStatus === "vip";
|
|
1169
1249
|
const reputation$1 = react.useMemo(() => {
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
const cooldownHours = reputation.TAKER_TIERS[tier].cooldownHours;
|
|
1186
|
-
let cooldownEndsAt = null;
|
|
1187
|
-
let isOnCooldown = false;
|
|
1188
|
-
const baseTimestamp = data.lastSignaledAt[chains.base.id] ?? null;
|
|
1189
|
-
const pulseTimestamp = data.lastSignaledAt[369] ?? null;
|
|
1190
|
-
const candidateTimestamps = isBase ? [baseTimestamp] : [baseTimestamp, pulseTimestamp];
|
|
1191
|
-
const lastSignaledTimestamp = candidateTimestamps.filter((ts) => ts !== null).sort((a, b) => Number(b) - Number(a))[0] ?? null;
|
|
1192
|
-
if (cooldownHours > 0 && lastSignaledTimestamp) {
|
|
1193
|
-
const lastSignaledTime = Number(lastSignaledTimestamp) * 1e3;
|
|
1194
|
-
const cooldownMs = cooldownHours * 60 * 60 * 1e3;
|
|
1195
|
-
cooldownEndsAt = new Date(lastSignaledTime + cooldownMs);
|
|
1196
|
-
isOnCooldown = cooldownEndsAt > /* @__PURE__ */ new Date();
|
|
1197
|
-
}
|
|
1198
|
-
return {
|
|
1199
|
-
tier,
|
|
1200
|
-
fulfilledVolume: data.fulfilledVolume,
|
|
1201
|
-
lockScore: dilutedLockScore,
|
|
1202
|
-
cooldownEndsAt,
|
|
1203
|
-
isOnCooldown
|
|
1204
|
-
};
|
|
1205
|
-
}, [reputationQuery.data, isBase]);
|
|
1206
|
-
const hasLoadedData = reputationQuery.data !== void 0;
|
|
1207
|
-
const isLoading = reputationQuery.isLoading && !hasLoadedData;
|
|
1208
|
-
const refetch = react.useCallback(() => {
|
|
1209
|
-
queryClient.invalidateQueries({
|
|
1210
|
-
queryKey: ["provex", "reputation", address]
|
|
1211
|
-
});
|
|
1212
|
-
}, [queryClient, address]);
|
|
1250
|
+
if (isDisabled) return reputation.DEFAULT_REPUTATION;
|
|
1251
|
+
const computed = computeUserReputation({ stats, pulseTimestamp: lastSignaledTimestamp });
|
|
1252
|
+
if (!canBypassCooldown) return computed;
|
|
1253
|
+
return { ...computed, tier: payment.tiers.PRESIDENT, isOnCooldown: false, cooldownEndsAt: null };
|
|
1254
|
+
}, [stats, lastSignaledTimestamp, canBypassCooldown, isDisabled]);
|
|
1255
|
+
const hasLoadedData = stats !== null;
|
|
1256
|
+
const isLoading = sourceLoading && !hasLoadedData;
|
|
1257
|
+
const refetch = react.useCallback(async () => {
|
|
1258
|
+
await refetchSource();
|
|
1259
|
+
}, [refetchSource]);
|
|
1260
|
+
const lastSignaledIntentMs = react.useMemo(
|
|
1261
|
+
() => lastSignaledTimestamp === null || lastSignaledTimestamp === void 0 ? null : Number(lastSignaledTimestamp) * 1e3,
|
|
1262
|
+
[lastSignaledTimestamp]
|
|
1263
|
+
);
|
|
1264
|
+
const filteringTier = isDisabled ? null : filteringTierFor({ vipStatus, tier: reputation$1.tier });
|
|
1213
1265
|
return {
|
|
1214
1266
|
reputation: reputation$1,
|
|
1267
|
+
lastSignaledIntentMs,
|
|
1268
|
+
vipStatus,
|
|
1269
|
+
filteringTier,
|
|
1215
1270
|
isLoading,
|
|
1216
|
-
error
|
|
1271
|
+
error,
|
|
1217
1272
|
refetch
|
|
1218
1273
|
};
|
|
1219
1274
|
}
|
|
1275
|
+
var NO_LIMITS = {
|
|
1276
|
+
hasLimits: false,
|
|
1277
|
+
noCooldownProviders: [],
|
|
1278
|
+
selectedProviderCooldownHours: 0,
|
|
1279
|
+
cooldownRemaining: null,
|
|
1280
|
+
isOnCooldown: false,
|
|
1281
|
+
effectiveCap: null,
|
|
1282
|
+
amountExceedsCap: false,
|
|
1283
|
+
capExceededMessage: null,
|
|
1284
|
+
tierName: null,
|
|
1285
|
+
tierBaseCapUsd: null,
|
|
1286
|
+
capMultiplier: null,
|
|
1287
|
+
effectiveCapUsd: null,
|
|
1288
|
+
providerName: null
|
|
1289
|
+
};
|
|
1290
|
+
var COOLDOWN_TICK_MS = 6e4;
|
|
1220
1291
|
function useReputationLimits({
|
|
1221
1292
|
chainId,
|
|
1222
1293
|
selectedPaymentMethod,
|
|
1223
1294
|
tier,
|
|
1224
1295
|
decimals,
|
|
1296
|
+
orderTokenAmount,
|
|
1225
1297
|
amountInInt,
|
|
1226
|
-
cooldownEndsAt
|
|
1298
|
+
cooldownEndsAt,
|
|
1299
|
+
disabled,
|
|
1300
|
+
clock
|
|
1227
1301
|
}) {
|
|
1228
|
-
const
|
|
1302
|
+
const provex = useOptionalProvex();
|
|
1303
|
+
const providerClock = useClock();
|
|
1304
|
+
const activeClock = clock ?? providerClock;
|
|
1305
|
+
const isDisabled = disabled ?? provex?.config.reputationDisabled ?? false;
|
|
1306
|
+
const hasLimits = !isDisabled;
|
|
1307
|
+
const orderAmount = orderTokenAmount ?? amountInInt ?? null;
|
|
1308
|
+
const [tick, setTick] = react.useState(0);
|
|
1309
|
+
react.useEffect(() => {
|
|
1310
|
+
if (!hasLimits || !cooldownEndsAt) return;
|
|
1311
|
+
const id = activeClock.setInterval(() => setTick((count) => count + 1), COOLDOWN_TICK_MS);
|
|
1312
|
+
return () => activeClock.clearInterval(id);
|
|
1313
|
+
}, [hasLimits, cooldownEndsAt, activeClock]);
|
|
1229
1314
|
const { cooldownRemaining, isOnCooldown } = react.useMemo(() => {
|
|
1230
|
-
const providerCooldownHours = reputation.getCooldownHours({ tier, providerKey: selectedPaymentMethod }) ;
|
|
1315
|
+
const providerCooldownHours = hasLimits ? reputation.getCooldownHours({ tier, providerKey: selectedPaymentMethod }) : 0;
|
|
1231
1316
|
const providerHasCooldown = providerCooldownHours > 0;
|
|
1232
1317
|
if (!cooldownEndsAt || !providerHasCooldown) {
|
|
1233
1318
|
return { cooldownRemaining: null, isOnCooldown: false };
|
|
1234
1319
|
}
|
|
1235
|
-
const remainingMs = cooldownEndsAt.getTime() -
|
|
1320
|
+
const remainingMs = cooldownEndsAt.getTime() - activeClock.now();
|
|
1236
1321
|
if (remainingMs <= 0) {
|
|
1237
1322
|
return { cooldownRemaining: null, isOnCooldown: false };
|
|
1238
1323
|
}
|
|
@@ -1240,8 +1325,9 @@ function useReputationLimits({
|
|
|
1240
1325
|
const minutes = Math.floor(remainingMs % (1e3 * 60 * 60) / (1e3 * 60));
|
|
1241
1326
|
const formatted = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
|
|
1242
1327
|
return { cooldownRemaining: formatted, isOnCooldown: true };
|
|
1243
|
-
}, [cooldownEndsAt, hasLimits, tier, selectedPaymentMethod]);
|
|
1328
|
+
}, [cooldownEndsAt, hasLimits, tier, selectedPaymentMethod, tick, activeClock]);
|
|
1244
1329
|
const noCooldownProviders = react.useMemo(() => {
|
|
1330
|
+
if (!hasLimits) return [];
|
|
1245
1331
|
const available = payment.verifiablePaymentMethods(chainId);
|
|
1246
1332
|
return available.filter((key) => {
|
|
1247
1333
|
if (key === selectedPaymentMethod) return false;
|
|
@@ -1251,22 +1337,43 @@ function useReputationLimits({
|
|
|
1251
1337
|
});
|
|
1252
1338
|
}, [hasLimits, chainId, selectedPaymentMethod, tier]);
|
|
1253
1339
|
const selectedProviderCooldownHours = react.useMemo(() => {
|
|
1340
|
+
if (!hasLimits) return 0;
|
|
1254
1341
|
return reputation.getCooldownHours({ tier, providerKey: selectedPaymentMethod });
|
|
1255
1342
|
}, [hasLimits, tier, selectedPaymentMethod]);
|
|
1256
1343
|
const effectiveCap = react.useMemo(() => {
|
|
1344
|
+
if (!hasLimits) return null;
|
|
1257
1345
|
return reputation.getEffectiveCap({ tier, providerKey: selectedPaymentMethod, decimals });
|
|
1258
1346
|
}, [hasLimits, tier, selectedPaymentMethod, decimals]);
|
|
1259
1347
|
const amountExceedsCap = react.useMemo(
|
|
1260
|
-
() => reputation.isOverOrderCap({ orderTokenAmount:
|
|
1261
|
-
[effectiveCap,
|
|
1348
|
+
() => reputation.isOverOrderCap({ orderTokenAmount: orderAmount, cap: effectiveCap }),
|
|
1349
|
+
[effectiveCap, orderAmount]
|
|
1262
1350
|
);
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1351
|
+
const tierName = react.useMemo(
|
|
1352
|
+
() => hasLimits ? reputation.TAKER_TIERS[tier].name : null,
|
|
1353
|
+
[hasLimits, tier]
|
|
1354
|
+
);
|
|
1355
|
+
const providerName = react.useMemo(
|
|
1356
|
+
() => hasLimits ? payment.providerConfigs(chainId)[selectedPaymentMethod]?.name ?? selectedPaymentMethod : null,
|
|
1357
|
+
[hasLimits, chainId, selectedPaymentMethod]
|
|
1358
|
+
);
|
|
1359
|
+
const tierBaseCapUsd = react.useMemo(
|
|
1360
|
+
() => hasLimits && effectiveCap !== null && effectiveCap !== reputation.UNLIMITED_CAP_BASE_UNITS ? reputation.TAKER_TIERS[tier].baseCap : null,
|
|
1361
|
+
[hasLimits, tier, effectiveCap]
|
|
1362
|
+
);
|
|
1363
|
+
const capMultiplier = react.useMemo(
|
|
1364
|
+
() => hasLimits && effectiveCap !== null && effectiveCap !== reputation.UNLIMITED_CAP_BASE_UNITS ? payment.getPlatformRisk(chainId, selectedPaymentMethod).capMultiplier ?? 1 : null,
|
|
1365
|
+
[hasLimits, chainId, selectedPaymentMethod, effectiveCap]
|
|
1366
|
+
);
|
|
1367
|
+
const effectiveCapUsd = react.useMemo(() => {
|
|
1368
|
+
if (!hasLimits || effectiveCap === null) return null;
|
|
1265
1369
|
if (effectiveCap === reputation.UNLIMITED_CAP_BASE_UNITS) return null;
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1370
|
+
return reputation.getEffectiveCapDisplayUsd(effectiveCap, decimals) ?? null;
|
|
1371
|
+
}, [hasLimits, effectiveCap, decimals]);
|
|
1372
|
+
const capExceededMessage = react.useMemo(() => {
|
|
1373
|
+
if (!amountExceedsCap || effectiveCapUsd === null || providerName === null) return null;
|
|
1374
|
+
return `Amount exceeds your $${effectiveCapUsd.toLocaleString()} limit for ${providerName}`;
|
|
1375
|
+
}, [amountExceedsCap, effectiveCapUsd, providerName]);
|
|
1376
|
+
if (!hasLimits) return NO_LIMITS;
|
|
1270
1377
|
return {
|
|
1271
1378
|
hasLimits,
|
|
1272
1379
|
noCooldownProviders,
|
|
@@ -1275,7 +1382,12 @@ function useReputationLimits({
|
|
|
1275
1382
|
isOnCooldown,
|
|
1276
1383
|
effectiveCap,
|
|
1277
1384
|
amountExceedsCap,
|
|
1278
|
-
capExceededMessage
|
|
1385
|
+
capExceededMessage,
|
|
1386
|
+
tierName,
|
|
1387
|
+
tierBaseCapUsd,
|
|
1388
|
+
capMultiplier,
|
|
1389
|
+
effectiveCapUsd,
|
|
1390
|
+
providerName
|
|
1279
1391
|
};
|
|
1280
1392
|
}
|
|
1281
1393
|
function usePayeeDetails({
|
|
@@ -1312,7 +1424,8 @@ function usePayeeDetails({
|
|
|
1312
1424
|
}, [indexedIntent]);
|
|
1313
1425
|
const expiryTime = indexedIntent?.expiryTime ?? null;
|
|
1314
1426
|
const depositQuery = reactQuery.useQuery({
|
|
1315
|
-
|
|
1427
|
+
// Query keys are hashed with JSON.stringify, which throws on bigint.
|
|
1428
|
+
queryKey: ["provex", "deposit", indexedIntent?.escrow, indexedIntent?.depositLocalId.toString(), chainId],
|
|
1316
1429
|
queryFn: () => indexer.getDepositWithVerifiers({
|
|
1317
1430
|
escrow: indexedIntent.escrow,
|
|
1318
1431
|
localId: indexedIntent.depositLocalId,
|
|
@@ -1660,36 +1773,100 @@ function useNullifierRegistry({
|
|
|
1660
1773
|
checkNullifierUsed
|
|
1661
1774
|
};
|
|
1662
1775
|
}
|
|
1663
|
-
function
|
|
1776
|
+
function encodeOrchestratorFulfill(attestation, verificationData, intentHash) {
|
|
1777
|
+
const args = [
|
|
1778
|
+
{
|
|
1779
|
+
paymentProof: utils.encodeV3PaymentProof(attestation),
|
|
1780
|
+
intentHash,
|
|
1781
|
+
verificationData,
|
|
1782
|
+
postIntentHookData: "0x"
|
|
1783
|
+
}
|
|
1784
|
+
];
|
|
1785
|
+
return {
|
|
1786
|
+
args,
|
|
1787
|
+
calldata: viem.encodeFunctionData({ abi: abis.OrchestratorAbi, functionName: "fulfillIntent", args }),
|
|
1788
|
+
abi: abis.OrchestratorAbi
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
function createWalletProvingClient(options) {
|
|
1664
1792
|
const {
|
|
1665
|
-
|
|
1793
|
+
orchestratorAddress,
|
|
1794
|
+
chainId,
|
|
1795
|
+
writeContract,
|
|
1796
|
+
publicClient: publicClient2,
|
|
1666
1797
|
checkNullifierUsed,
|
|
1798
|
+
getGasInputs,
|
|
1799
|
+
encodeFulfill = encodeOrchestratorFulfill,
|
|
1800
|
+
onPrefill
|
|
1801
|
+
} = options;
|
|
1802
|
+
return {
|
|
1803
|
+
chainId,
|
|
1804
|
+
async fulfillIntent(params) {
|
|
1805
|
+
const context = { chainId, request: void 0 };
|
|
1806
|
+
const gasInputs = await getGasInputs();
|
|
1807
|
+
const { args, calldata, abi } = encodeFulfill(
|
|
1808
|
+
params.attestation,
|
|
1809
|
+
params.verificationData,
|
|
1810
|
+
params.intentHash
|
|
1811
|
+
);
|
|
1812
|
+
params.onAwaitingSignature?.(context);
|
|
1813
|
+
const hash = await writeContract({
|
|
1814
|
+
address: orchestratorAddress,
|
|
1815
|
+
abi,
|
|
1816
|
+
functionName: "fulfillIntent",
|
|
1817
|
+
args,
|
|
1818
|
+
chainId,
|
|
1819
|
+
...gasInputs
|
|
1820
|
+
});
|
|
1821
|
+
onPrefill?.(
|
|
1822
|
+
{
|
|
1823
|
+
to: orchestratorAddress,
|
|
1824
|
+
data: calldata,
|
|
1825
|
+
value: 0n,
|
|
1826
|
+
originalTip: gasInputs.maxPriorityFeePerGas
|
|
1827
|
+
},
|
|
1828
|
+
gasInputs,
|
|
1829
|
+
hash
|
|
1830
|
+
);
|
|
1831
|
+
params.onTransactionHash?.({ ...context, hash });
|
|
1832
|
+
const receipt = publicClient2 ? await publicClient2.waitForTransactionReceipt({ hash }) : void 0;
|
|
1833
|
+
return { hash, receipt };
|
|
1834
|
+
},
|
|
1835
|
+
async checkNullifierUsed({ nullifier }) {
|
|
1836
|
+
return checkNullifierUsed(nullifier);
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
// src/hooks/useProvingFlow.ts
|
|
1842
|
+
function useProvingFlow(options) {
|
|
1843
|
+
const {
|
|
1844
|
+
rail,
|
|
1667
1845
|
request,
|
|
1668
1846
|
paymentMethodId,
|
|
1669
1847
|
captureAdapter,
|
|
1670
1848
|
attestationBaseUrl,
|
|
1849
|
+
attestationServiceUrl,
|
|
1671
1850
|
onAwaitingSignature,
|
|
1672
1851
|
onTransactionHash,
|
|
1673
1852
|
onComplete
|
|
1674
|
-
} =
|
|
1675
|
-
const
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
}),
|
|
1685
|
-
[proveXClient, checkNullifierUsed, request.chainId]
|
|
1686
|
-
);
|
|
1853
|
+
} = options;
|
|
1854
|
+
const chainId = options.chainId ?? request.chainId;
|
|
1855
|
+
const client = react.useMemo(() => {
|
|
1856
|
+
if (rail.kind === "wallet") return createWalletProvingClient({ ...rail, chainId });
|
|
1857
|
+
return {
|
|
1858
|
+
chainId,
|
|
1859
|
+
fulfillIntent: rail.fulfillIntent,
|
|
1860
|
+
checkNullifierUsed: ({ nullifier }) => rail.checkNullifierUsed(nullifier)
|
|
1861
|
+
};
|
|
1862
|
+
}, [rail, chainId]);
|
|
1687
1863
|
const resolvedCaptureAdapter = react.useMemo(
|
|
1688
1864
|
() => captureAdapter ?? extensionReact.createExtensionEnclaveAdapter({
|
|
1689
1865
|
getPeer: () => window.peer,
|
|
1690
|
-
attestationBaseUrl
|
|
1866
|
+
attestationBaseUrl,
|
|
1867
|
+
...attestationServiceUrl ? { attestationServiceUrl } : {}
|
|
1691
1868
|
}),
|
|
1692
|
-
[captureAdapter, attestationBaseUrl]
|
|
1869
|
+
[captureAdapter, attestationBaseUrl, attestationServiceUrl]
|
|
1693
1870
|
);
|
|
1694
1871
|
const manualSelect = proving.useManualTransactionSelect();
|
|
1695
1872
|
const { state, authenticate, fulfill, retryVerification, retrySubmission } = proving.useProving({
|
|
@@ -1705,6 +1882,17 @@ function useProvexProving(deps) {
|
|
|
1705
1882
|
return { state, authenticate, fulfill, retryVerification, retrySubmission, manualSelect };
|
|
1706
1883
|
}
|
|
1707
1884
|
|
|
1885
|
+
// src/hooks/useProvexProving.ts
|
|
1886
|
+
function useProvexProving(deps) {
|
|
1887
|
+
const { proveXClient, checkNullifierUsed, ...flowOptions } = deps;
|
|
1888
|
+
const { fulfillIntent } = proveXClient;
|
|
1889
|
+
const rail = react.useMemo(
|
|
1890
|
+
() => ({ kind: "client", fulfillIntent, checkNullifierUsed }),
|
|
1891
|
+
[fulfillIntent, checkNullifierUsed]
|
|
1892
|
+
);
|
|
1893
|
+
return useProvingFlow({ rail, ...flowOptions });
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1708
1896
|
// src/useProvexBuy.ts
|
|
1709
1897
|
function parseAmountSafe(value, decimals) {
|
|
1710
1898
|
if (!value || value === "." || value === "0.") return null;
|
|
@@ -1746,10 +1934,8 @@ function useProvexBuy({
|
|
|
1746
1934
|
paymentMethod: activePaymentMethod,
|
|
1747
1935
|
currency
|
|
1748
1936
|
});
|
|
1749
|
-
const { reputation
|
|
1750
|
-
address: wallet.address
|
|
1751
|
-
chainId
|
|
1752
|
-
});
|
|
1937
|
+
const { reputation } = useUserReputation({
|
|
1938
|
+
address: wallet.address});
|
|
1753
1939
|
const amountBigInt = react.useMemo(
|
|
1754
1940
|
() => parseAmountSafe(amount, currency.decimals),
|
|
1755
1941
|
[amount, currency.decimals]
|
|
@@ -1785,12 +1971,11 @@ function useProvexBuy({
|
|
|
1785
1971
|
refetchAllRef.current = payeeResult.refetchAll;
|
|
1786
1972
|
react.useEffect(() => {
|
|
1787
1973
|
if (phase !== "committed") return;
|
|
1788
|
-
if (!intentHash) return;
|
|
1789
1974
|
const interval = setInterval(() => {
|
|
1790
1975
|
refetchAllRef.current();
|
|
1791
1976
|
}, 5e3);
|
|
1792
1977
|
return () => clearInterval(interval);
|
|
1793
|
-
}, [phase
|
|
1978
|
+
}, [phase]);
|
|
1794
1979
|
react.useEffect(() => {
|
|
1795
1980
|
if (!payeeResult.isPruned) return;
|
|
1796
1981
|
if (phase === "browse") return;
|
|
@@ -1830,6 +2015,7 @@ function useProvexBuy({
|
|
|
1830
2015
|
payeeDetailsHash,
|
|
1831
2016
|
token,
|
|
1832
2017
|
intent: {
|
|
2018
|
+
owner: intent.owner,
|
|
1833
2019
|
amount: intent.amount,
|
|
1834
2020
|
timestamp: intent.timestamp,
|
|
1835
2021
|
paymentMethod: intent.paymentMethod,
|
|
@@ -1848,6 +2034,7 @@ function useProvexBuy({
|
|
|
1848
2034
|
token: token ?? { decimals: 18 },
|
|
1849
2035
|
intent: {
|
|
1850
2036
|
intentHash: intentHash ?? "0x",
|
|
2037
|
+
owner: "0x",
|
|
1851
2038
|
amount: "0",
|
|
1852
2039
|
timestampMs: "0",
|
|
1853
2040
|
paymentMethod: "0x",
|
|
@@ -1909,10 +2096,10 @@ function useProvexBuy({
|
|
|
1909
2096
|
const limits = useReputationLimits({
|
|
1910
2097
|
chainId,
|
|
1911
2098
|
selectedPaymentMethod: activePaymentMethod,
|
|
1912
|
-
tier: reputation
|
|
2099
|
+
tier: reputation.tier,
|
|
1913
2100
|
decimals: tokenDecimals,
|
|
1914
|
-
|
|
1915
|
-
cooldownEndsAt: reputation
|
|
2101
|
+
orderTokenAmount: tokenAmount,
|
|
2102
|
+
cooldownEndsAt: reputation.cooldownEndsAt
|
|
1916
2103
|
});
|
|
1917
2104
|
const rateDisplay = react.useMemo(() => {
|
|
1918
2105
|
if (!bestRate || !token) return null;
|
|
@@ -1998,7 +2185,7 @@ function useProvexBuy({
|
|
|
1998
2185
|
tokenAmountDisplay,
|
|
1999
2186
|
token,
|
|
2000
2187
|
currency,
|
|
2001
|
-
reputation
|
|
2188
|
+
reputation,
|
|
2002
2189
|
limits,
|
|
2003
2190
|
feePercentage: feeInfo?.percentage ?? null,
|
|
2004
2191
|
payeeDetails: payeeResult.payeeDetails,
|