@unifold/headless-react 0.1.70-beta.1
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/README.md +198 -0
- package/dist/index.d.mts +218 -0
- package/dist/index.d.ts +218 -0
- package/dist/index.js +420 -0
- package/dist/index.mjs +402 -0
- package/package.json +63 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { UnifoldProvider, useUnifold as useUnifold8 } from "@unifold/react-provider";
|
|
3
|
+
|
|
4
|
+
// src/use-unifold-client.ts
|
|
5
|
+
import { useMemo } from "react";
|
|
6
|
+
import { createUnifoldClient } from "@unifold/core";
|
|
7
|
+
import { useUnifold } from "@unifold/react-provider";
|
|
8
|
+
function useUnifoldClient() {
|
|
9
|
+
const { publishableKey } = useUnifold();
|
|
10
|
+
return useMemo(
|
|
11
|
+
() => publishableKey ? createUnifoldClient({ publishableKey }) : null,
|
|
12
|
+
[publishableKey]
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/use-deposit.ts
|
|
17
|
+
import { useCallback, useEffect, useMemo as useMemo2, useRef, useState, useSyncExternalStore } from "react";
|
|
18
|
+
import {
|
|
19
|
+
DepositSession,
|
|
20
|
+
DepositSessionEventType
|
|
21
|
+
} from "@unifold/core";
|
|
22
|
+
import { useUnifold as useUnifold2 } from "@unifold/react-provider";
|
|
23
|
+
var IDLE_SNAPSHOT = {
|
|
24
|
+
status: "idle",
|
|
25
|
+
addresses: [],
|
|
26
|
+
executions: [],
|
|
27
|
+
latestExecution: null,
|
|
28
|
+
isCheckingDeposit: false,
|
|
29
|
+
error: null
|
|
30
|
+
};
|
|
31
|
+
function useDeposit(options) {
|
|
32
|
+
const { publishableKey } = useUnifold2();
|
|
33
|
+
const {
|
|
34
|
+
externalUserId,
|
|
35
|
+
destination,
|
|
36
|
+
confirmationMode = "auto",
|
|
37
|
+
method,
|
|
38
|
+
autoStart = true
|
|
39
|
+
} = options;
|
|
40
|
+
const callbacksRef = useRef(options);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
callbacksRef.current = options;
|
|
43
|
+
});
|
|
44
|
+
const [session, setSession] = useState(null);
|
|
45
|
+
const sessionKey = [
|
|
46
|
+
publishableKey,
|
|
47
|
+
externalUserId ?? "",
|
|
48
|
+
destination.chainType,
|
|
49
|
+
destination.chainId,
|
|
50
|
+
destination.tokenAddress,
|
|
51
|
+
destination.recipientAddress,
|
|
52
|
+
JSON.stringify(destination.contractCalls ?? null),
|
|
53
|
+
confirmationMode,
|
|
54
|
+
method ?? ""
|
|
55
|
+
].join("|");
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!publishableKey || !externalUserId) {
|
|
58
|
+
setSession(null);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const nextSession = new DepositSession({
|
|
62
|
+
publishableKey,
|
|
63
|
+
externalUserId,
|
|
64
|
+
destination,
|
|
65
|
+
confirmationMode,
|
|
66
|
+
method
|
|
67
|
+
});
|
|
68
|
+
let previousStatus = nextSession.getSnapshot().status;
|
|
69
|
+
const offEvents = nextSession.on("*", (event) => {
|
|
70
|
+
const callbacks = callbacksRef.current;
|
|
71
|
+
callbacks.onEvent?.(event);
|
|
72
|
+
switch (event.type) {
|
|
73
|
+
case DepositSessionEventType.ADDRESSES_CREATED:
|
|
74
|
+
callbacks.onAddressesReady?.(event.data.object.addresses);
|
|
75
|
+
break;
|
|
76
|
+
case DepositSessionEventType.EXECUTION_DETECTED:
|
|
77
|
+
callbacks.onExecutionDetected?.(event.data.object);
|
|
78
|
+
break;
|
|
79
|
+
case DepositSessionEventType.EXECUTION_UPDATED:
|
|
80
|
+
callbacks.onExecutionUpdated?.(event.data.object);
|
|
81
|
+
break;
|
|
82
|
+
case DepositSessionEventType.EXECUTION_SUCCEEDED:
|
|
83
|
+
callbacks.onSuccess?.(event.data.object);
|
|
84
|
+
break;
|
|
85
|
+
case DepositSessionEventType.EXECUTION_FAILED:
|
|
86
|
+
callbacks.onError?.({
|
|
87
|
+
code: "DEPOSIT_FAILED",
|
|
88
|
+
message: "Deposit failed",
|
|
89
|
+
fatal: false,
|
|
90
|
+
cause: event.data.object
|
|
91
|
+
});
|
|
92
|
+
break;
|
|
93
|
+
case DepositSessionEventType.SESSION_ERRORED:
|
|
94
|
+
callbacks.onError?.({
|
|
95
|
+
code: event.data.object.code,
|
|
96
|
+
message: event.data.object.message,
|
|
97
|
+
fatal: event.data.object.fatal
|
|
98
|
+
});
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
const offStatus = nextSession.subscribe(() => {
|
|
103
|
+
const status = nextSession.getSnapshot().status;
|
|
104
|
+
if (status !== previousStatus) {
|
|
105
|
+
previousStatus = status;
|
|
106
|
+
callbacksRef.current.onStatusChange?.(status);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
setSession(nextSession);
|
|
110
|
+
if (autoStart) {
|
|
111
|
+
void nextSession.start();
|
|
112
|
+
}
|
|
113
|
+
return () => {
|
|
114
|
+
offEvents();
|
|
115
|
+
offStatus();
|
|
116
|
+
nextSession.destroy();
|
|
117
|
+
};
|
|
118
|
+
}, [sessionKey, autoStart]);
|
|
119
|
+
const subscribe = useCallback(
|
|
120
|
+
(listener) => session ? session.subscribe(listener) : () => {
|
|
121
|
+
},
|
|
122
|
+
[session]
|
|
123
|
+
);
|
|
124
|
+
const getSnapshot = useCallback(
|
|
125
|
+
() => session ? session.getSnapshot() : IDLE_SNAPSHOT,
|
|
126
|
+
[session]
|
|
127
|
+
);
|
|
128
|
+
const snapshot = useSyncExternalStore(subscribe, getSnapshot, () => IDLE_SNAPSHOT);
|
|
129
|
+
const getAddress = useCallback(
|
|
130
|
+
(query) => snapshot.addresses.find((a) => a.chainType === query.chainType),
|
|
131
|
+
[snapshot.addresses]
|
|
132
|
+
);
|
|
133
|
+
const controls = useMemo2(
|
|
134
|
+
() => ({
|
|
135
|
+
start: () => session?.start() ?? Promise.resolve(),
|
|
136
|
+
confirmFundsSent: () => session?.confirmFundsSent(),
|
|
137
|
+
stop: () => session?.stop(),
|
|
138
|
+
restart: async () => {
|
|
139
|
+
if (!session) return;
|
|
140
|
+
session.stop();
|
|
141
|
+
await session.start();
|
|
142
|
+
}
|
|
143
|
+
}),
|
|
144
|
+
[session]
|
|
145
|
+
);
|
|
146
|
+
return {
|
|
147
|
+
status: snapshot.status,
|
|
148
|
+
addresses: snapshot.addresses,
|
|
149
|
+
getAddress,
|
|
150
|
+
executions: snapshot.executions,
|
|
151
|
+
latestExecution: snapshot.latestExecution,
|
|
152
|
+
isCheckingDeposit: snapshot.isCheckingDeposit,
|
|
153
|
+
error: snapshot.error,
|
|
154
|
+
...controls,
|
|
155
|
+
session
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// src/use-deposit-addresses.ts
|
|
160
|
+
import { useQuery } from "@tanstack/react-query";
|
|
161
|
+
import {
|
|
162
|
+
createDepositAddress,
|
|
163
|
+
mapWalletToDepositAddress
|
|
164
|
+
} from "@unifold/core";
|
|
165
|
+
import { useUnifold as useUnifold3 } from "@unifold/react-provider";
|
|
166
|
+
function useDepositAddresses(options) {
|
|
167
|
+
const { publishableKey } = useUnifold3();
|
|
168
|
+
const { externalUserId, destination, actionType, enabled = true } = options;
|
|
169
|
+
return useQuery({
|
|
170
|
+
// Key parity with @unifold/ui-react's useDepositAddress — do not reorder.
|
|
171
|
+
queryKey: [
|
|
172
|
+
"unifold",
|
|
173
|
+
"depositAddress",
|
|
174
|
+
externalUserId,
|
|
175
|
+
destination?.recipientAddress ?? null,
|
|
176
|
+
destination?.chainType ?? null,
|
|
177
|
+
destination?.chainId ?? null,
|
|
178
|
+
destination?.tokenAddress ?? null,
|
|
179
|
+
actionType ?? null,
|
|
180
|
+
destination?.contractCalls ?? null,
|
|
181
|
+
publishableKey
|
|
182
|
+
],
|
|
183
|
+
queryFn: () => createDepositAddress(
|
|
184
|
+
{
|
|
185
|
+
external_user_id: externalUserId,
|
|
186
|
+
recipient_address: destination?.recipientAddress,
|
|
187
|
+
destination_chain_type: destination?.chainType,
|
|
188
|
+
destination_chain_id: destination?.chainId,
|
|
189
|
+
destination_token_address: destination?.tokenAddress,
|
|
190
|
+
action_type: actionType,
|
|
191
|
+
contract_calls: destination?.contractCalls
|
|
192
|
+
},
|
|
193
|
+
publishableKey
|
|
194
|
+
),
|
|
195
|
+
select: (response) => response.data.map(mapWalletToDepositAddress),
|
|
196
|
+
enabled: enabled && !!externalUserId && !!publishableKey,
|
|
197
|
+
staleTime: 1e3 * 60 * 60,
|
|
198
|
+
// 1 hour — wallets don't change once created
|
|
199
|
+
gcTime: 1e3 * 60 * 60 * 24,
|
|
200
|
+
refetchOnMount: false,
|
|
201
|
+
refetchOnWindowFocus: false,
|
|
202
|
+
retry: 3,
|
|
203
|
+
retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// src/use-supported-deposit-tokens.ts
|
|
208
|
+
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
209
|
+
import {
|
|
210
|
+
getSupportedDepositTokens
|
|
211
|
+
} from "@unifold/core";
|
|
212
|
+
import { useUnifold as useUnifold4 } from "@unifold/react-provider";
|
|
213
|
+
function useSupportedDepositTokens(options = {}) {
|
|
214
|
+
const { publishableKey } = useUnifold4();
|
|
215
|
+
const { destination, productType, enabled = true } = options;
|
|
216
|
+
const apiOptions = destination || productType ? {
|
|
217
|
+
...destination ? {
|
|
218
|
+
destination_token_address: destination.tokenAddress,
|
|
219
|
+
destination_chain_id: destination.chainId,
|
|
220
|
+
destination_chain_type: destination.chainType
|
|
221
|
+
} : {},
|
|
222
|
+
...productType ? { product_type: productType } : {}
|
|
223
|
+
} : void 0;
|
|
224
|
+
return useQuery2({
|
|
225
|
+
// Key parity with @unifold/ui-react's useSupportedDepositTokens.
|
|
226
|
+
queryKey: [
|
|
227
|
+
"unifold",
|
|
228
|
+
"supportedDepositTokens",
|
|
229
|
+
publishableKey,
|
|
230
|
+
destination?.tokenAddress ?? null,
|
|
231
|
+
destination?.chainId ?? null,
|
|
232
|
+
destination?.chainType ?? null,
|
|
233
|
+
productType ?? null
|
|
234
|
+
],
|
|
235
|
+
queryFn: () => getSupportedDepositTokens(publishableKey, apiOptions),
|
|
236
|
+
select: (response) => response.data,
|
|
237
|
+
enabled: enabled && !!publishableKey,
|
|
238
|
+
staleTime: 1e3 * 60 * 5,
|
|
239
|
+
gcTime: 1e3 * 60 * 30,
|
|
240
|
+
refetchOnMount: false,
|
|
241
|
+
refetchOnWindowFocus: false
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/use-executions.ts
|
|
246
|
+
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
247
|
+
import {
|
|
248
|
+
queryExecutions,
|
|
249
|
+
mapDirectExecution,
|
|
250
|
+
ActionType
|
|
251
|
+
} from "@unifold/core";
|
|
252
|
+
import { useUnifold as useUnifold5 } from "@unifold/react-provider";
|
|
253
|
+
function useExecutions(options) {
|
|
254
|
+
const { publishableKey } = useUnifold5();
|
|
255
|
+
const { externalUserId, refetchInterval = false, enabled = true, actionType = ActionType.Deposit } = options;
|
|
256
|
+
return useQuery3({
|
|
257
|
+
// Key parity with @unifold/ui-react's useExecutions.
|
|
258
|
+
queryKey: ["unifold", "executions", actionType, externalUserId, publishableKey],
|
|
259
|
+
queryFn: () => queryExecutions(externalUserId, publishableKey, actionType),
|
|
260
|
+
select: (response) => response.data.map(mapDirectExecution),
|
|
261
|
+
enabled: enabled && !!externalUserId && !!publishableKey,
|
|
262
|
+
refetchInterval,
|
|
263
|
+
staleTime: 0,
|
|
264
|
+
gcTime: 1e3 * 60 * 5,
|
|
265
|
+
refetchOnWindowFocus: false
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/use-allowed-country.ts
|
|
270
|
+
import { useQuery as useQuery4, keepPreviousData } from "@tanstack/react-query";
|
|
271
|
+
import { getIpAddress, getProjectConfig } from "@unifold/core";
|
|
272
|
+
import { useUnifold as useUnifold6 } from "@unifold/react-provider";
|
|
273
|
+
function useAllowedCountry() {
|
|
274
|
+
const { publishableKey } = useUnifold6();
|
|
275
|
+
const ipQuery = useQuery4({
|
|
276
|
+
// Key parity with @unifold/core's useUserIp.
|
|
277
|
+
queryKey: ["unifold", "userIpInfo"],
|
|
278
|
+
queryFn: async () => {
|
|
279
|
+
const data = await getIpAddress();
|
|
280
|
+
const subdivision = data.subdivision_code || data.state || null;
|
|
281
|
+
return { alpha2: data.alpha2, country: data.country, subdivisionCode: subdivision };
|
|
282
|
+
},
|
|
283
|
+
refetchOnMount: false,
|
|
284
|
+
refetchOnReconnect: true,
|
|
285
|
+
refetchOnWindowFocus: false,
|
|
286
|
+
staleTime: 1e3 * 60 * 60,
|
|
287
|
+
gcTime: 1e3 * 60 * 60 * 24
|
|
288
|
+
});
|
|
289
|
+
const ip = ipQuery.data;
|
|
290
|
+
const configQuery = useQuery4({
|
|
291
|
+
// Key parity with @unifold/ui-react's useProjectConfig.
|
|
292
|
+
queryKey: ip?.alpha2 ? ["unifold", "projectConfig", publishableKey, ip.alpha2, ip.subdivisionCode ?? null] : ["unifold", "projectConfig", publishableKey],
|
|
293
|
+
queryFn: () => getProjectConfig(
|
|
294
|
+
publishableKey,
|
|
295
|
+
ip?.alpha2 ? { countryCode: ip.alpha2, subdivisionCode: ip.subdivisionCode ?? void 0 } : void 0
|
|
296
|
+
),
|
|
297
|
+
enabled: !!publishableKey && !ipQuery.isLoading,
|
|
298
|
+
placeholderData: keepPreviousData,
|
|
299
|
+
staleTime: 1e3 * 60 * 30
|
|
300
|
+
});
|
|
301
|
+
const isLoading = ipQuery.isLoading || configQuery.isLoading;
|
|
302
|
+
const error = ipQuery.error || configQuery.error || null;
|
|
303
|
+
const projectConfig = configQuery.data;
|
|
304
|
+
let isAllowed = null;
|
|
305
|
+
if (ip && projectConfig) {
|
|
306
|
+
const blockedCodes = projectConfig.blocked_country_codes || [];
|
|
307
|
+
const blockedSubdivisions = projectConfig.blocked_country_subdivisions || [];
|
|
308
|
+
const countryUpper = ip.alpha2.toUpperCase();
|
|
309
|
+
const subdivisionUpper = (ip.subdivisionCode ?? "").toUpperCase();
|
|
310
|
+
const countryBlocked = blockedCodes.some((code) => code.toUpperCase() === countryUpper);
|
|
311
|
+
const subdivisionBlocked = blockedSubdivisions.some((entry) => {
|
|
312
|
+
if (entry.country_code.toUpperCase() !== countryUpper) return false;
|
|
313
|
+
return entry.subdivision_codes.some((code) => code.toUpperCase() === subdivisionUpper);
|
|
314
|
+
});
|
|
315
|
+
isAllowed = !countryBlocked && !subdivisionBlocked;
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
isAllowed,
|
|
319
|
+
alpha2: ip?.alpha2 ?? null,
|
|
320
|
+
country: ip?.country ?? null,
|
|
321
|
+
subdivisionCode: ip?.subdivisionCode ?? null,
|
|
322
|
+
isLoading,
|
|
323
|
+
error
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/use-address-validation.ts
|
|
328
|
+
import { useQuery as useQuery5 } from "@tanstack/react-query";
|
|
329
|
+
import {
|
|
330
|
+
verifyRecipientAddress
|
|
331
|
+
} from "@unifold/core";
|
|
332
|
+
import { useUnifold as useUnifold7 } from "@unifold/react-provider";
|
|
333
|
+
function useAddressValidation(options) {
|
|
334
|
+
const { publishableKey } = useUnifold7();
|
|
335
|
+
const { recipientAddress, destination, enabled = true } = options;
|
|
336
|
+
const shouldValidate = enabled && !!publishableKey && !!recipientAddress && !!destination;
|
|
337
|
+
const { data, isLoading, error } = useQuery5({
|
|
338
|
+
// Key parity with @unifold/ui-react's useAddressValidation.
|
|
339
|
+
queryKey: [
|
|
340
|
+
"unifold",
|
|
341
|
+
"addressValidation",
|
|
342
|
+
recipientAddress,
|
|
343
|
+
destination?.chainType,
|
|
344
|
+
destination?.chainId,
|
|
345
|
+
destination?.tokenAddress
|
|
346
|
+
],
|
|
347
|
+
queryFn: () => verifyRecipientAddress(
|
|
348
|
+
{
|
|
349
|
+
chain_type: destination.chainType,
|
|
350
|
+
chain_id: destination.chainId,
|
|
351
|
+
token_address: destination.tokenAddress,
|
|
352
|
+
recipient_address: recipientAddress
|
|
353
|
+
},
|
|
354
|
+
publishableKey
|
|
355
|
+
),
|
|
356
|
+
enabled: shouldValidate,
|
|
357
|
+
refetchOnMount: false,
|
|
358
|
+
refetchOnReconnect: false,
|
|
359
|
+
refetchOnWindowFocus: false,
|
|
360
|
+
staleTime: 1e3 * 60 * 5,
|
|
361
|
+
gcTime: 1e3 * 60 * 30
|
|
362
|
+
});
|
|
363
|
+
if (!shouldValidate) {
|
|
364
|
+
return { isValid: null, failureCode: null, metadata: null, isLoading: false, error: null };
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
isValid: data?.valid ?? null,
|
|
368
|
+
failureCode: data?.failure_code ?? null,
|
|
369
|
+
metadata: data?.metadata ?? null,
|
|
370
|
+
isLoading,
|
|
371
|
+
error: error ?? null
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// src/index.ts
|
|
376
|
+
import {
|
|
377
|
+
createUnifoldClient as createUnifoldClient2,
|
|
378
|
+
UnifoldClient,
|
|
379
|
+
DepositSession as DepositSession2,
|
|
380
|
+
DepositSessionEventType as DepositSessionEventType2,
|
|
381
|
+
DepositSessionWaitError,
|
|
382
|
+
ExecutionStatus as ExecutionStatus2,
|
|
383
|
+
ActionType as ActionType2
|
|
384
|
+
} from "@unifold/core";
|
|
385
|
+
export {
|
|
386
|
+
ActionType2 as ActionType,
|
|
387
|
+
DepositSession2 as DepositSession,
|
|
388
|
+
DepositSessionEventType2 as DepositSessionEventType,
|
|
389
|
+
DepositSessionWaitError,
|
|
390
|
+
ExecutionStatus2 as ExecutionStatus,
|
|
391
|
+
UnifoldClient,
|
|
392
|
+
UnifoldProvider,
|
|
393
|
+
createUnifoldClient2 as createUnifoldClient,
|
|
394
|
+
useAddressValidation,
|
|
395
|
+
useAllowedCountry,
|
|
396
|
+
useDeposit,
|
|
397
|
+
useDepositAddresses,
|
|
398
|
+
useExecutions,
|
|
399
|
+
useSupportedDepositTokens,
|
|
400
|
+
useUnifold8 as useUnifold,
|
|
401
|
+
useUnifoldClient
|
|
402
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@unifold/headless-react",
|
|
3
|
+
"version": "0.1.70-beta.1",
|
|
4
|
+
"description": "Unifold Headless React SDK - hooks-only (no UI) crypto deposit flows",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": "^18.2.0 || ^19.0.0"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@tanstack/react-query": "^5.90.11",
|
|
24
|
+
"@unifold/core": "0.1.70-beta.1",
|
|
25
|
+
"@unifold/react-provider": "0.1.70-beta.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/react": "^19.0.0",
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
30
|
+
"@typescript-eslint/parser": "^6.21.0",
|
|
31
|
+
"eslint": "^8.57.0",
|
|
32
|
+
"eslint-config-prettier": "^9.1.0",
|
|
33
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
34
|
+
"eslint-plugin-react": "^7.34.1",
|
|
35
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
36
|
+
"prettier": "^3.2.5",
|
|
37
|
+
"react": "^19.0.0",
|
|
38
|
+
"tsup": "^8.0.0",
|
|
39
|
+
"typescript": "^5.0.0"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"unifold",
|
|
43
|
+
"headless",
|
|
44
|
+
"hooks",
|
|
45
|
+
"react",
|
|
46
|
+
"sdk",
|
|
47
|
+
"crypto",
|
|
48
|
+
"deposit",
|
|
49
|
+
"web3"
|
|
50
|
+
],
|
|
51
|
+
"author": "unifold.io",
|
|
52
|
+
"license": "Apache-2.0",
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsup",
|
|
55
|
+
"dev": "tsup --watch",
|
|
56
|
+
"clean": "rm -rf dist",
|
|
57
|
+
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
|
58
|
+
"lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
|
|
59
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
60
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
61
|
+
"type-check": "tsc --noEmit"
|
|
62
|
+
}
|
|
63
|
+
}
|