@frak-labs/nexus-sdk 0.0.1-alpha
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/LICENSE +674 -0
- package/README.md +70 -0
- package/dist/chunk-4X75PGSK.cjs +160 -0
- package/dist/chunk-JE64MPH2.js +160 -0
- package/dist/client-SCwoh_kP.d.cts +246 -0
- package/dist/client-SCwoh_kP.d.ts +246 -0
- package/dist/core/actions/index.cjs +77 -0
- package/dist/core/actions/index.d.cts +63 -0
- package/dist/core/actions/index.d.ts +63 -0
- package/dist/core/actions/index.js +77 -0
- package/dist/core/index.cjs +179 -0
- package/dist/core/index.d.cts +83 -0
- package/dist/core/index.d.ts +83 -0
- package/dist/core/index.js +179 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +0 -0
- package/package.json +55 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { a as FrakWalletSdkConfig, F as FrakClient, E as ExtractedParametersFromRpc, I as IFrameRpcSchema, c as ExtractedReturnTypeFromRpc, R as RedirectRpcSchema } from '../client-SCwoh_kP.cjs';
|
|
2
|
+
export { A as ArticleUnlockStatusReturnType, f as IFrameEvent, e as IFrameRpcEvent, d as IFrameTransport, P as PaidArticleUnlockPrice, b as StartArticleUnlockParams, S as StartArticleUnlockReturnType, U as UnlockOptionsReturnType, W as WalletStatusReturnType } from '../client-SCwoh_kP.cjs';
|
|
3
|
+
import 'viem';
|
|
4
|
+
import 'viem/chains';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a new iframe Frak client
|
|
8
|
+
*/
|
|
9
|
+
declare function createIFrameFrakClient({ config, iframe, }: {
|
|
10
|
+
config: FrakWalletSdkConfig;
|
|
11
|
+
iframe: HTMLIFrameElement;
|
|
12
|
+
}): FrakClient;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create the given iframe
|
|
16
|
+
* @param walletBaseUrl
|
|
17
|
+
*/
|
|
18
|
+
declare function createIframe({ walletBaseUrl, }: {
|
|
19
|
+
walletBaseUrl: string;
|
|
20
|
+
}): Promise<HTMLIFrameElement | undefined>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The received encoded data from a client
|
|
24
|
+
* -> The encoded should contain a HashProtectedData once decoded
|
|
25
|
+
*/
|
|
26
|
+
type CompressedData = Readonly<{
|
|
27
|
+
compressed: string;
|
|
28
|
+
compressedHash: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* The encoded data to send to a client / received by a client
|
|
32
|
+
*/
|
|
33
|
+
type HashProtectedData<DataType> = Readonly<DataType & {
|
|
34
|
+
validationHash: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Represent a key provider used for the hashed and secure compression
|
|
38
|
+
*/
|
|
39
|
+
type KeyProvider<DataType> = (value: DataType) => string[];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Compress the given params, and add hash protection to (rapidly) prevent interception modification
|
|
43
|
+
* @param data The params to encode
|
|
44
|
+
* @param keyProvider The method used to access the keys
|
|
45
|
+
*/
|
|
46
|
+
declare function hashAndCompressData<T>(data: T, keyProvider: KeyProvider<T>): Promise<CompressedData>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Decompress the given string
|
|
50
|
+
* @param compressedData The params to encode
|
|
51
|
+
* @param keyAccessor The key accessor used to query the keys used for the validation hash
|
|
52
|
+
*/
|
|
53
|
+
declare function decompressDataAndCheckHash<T>(compressedData: CompressedData, keyAccessor: KeyProvider<T>): Promise<HashProtectedData<T>>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the right request key provider for the given args
|
|
57
|
+
* @param args
|
|
58
|
+
*/
|
|
59
|
+
declare const iFrameRequestKeyProvider: KeyProvider<ExtractedParametersFromRpc<IFrameRpcSchema>>;
|
|
60
|
+
type RpcResponseKeyProvider<TParameters extends Pick<ExtractedParametersFromRpc<IFrameRpcSchema>, "method">> = KeyProvider<ExtractedReturnTypeFromRpc<IFrameRpcSchema, Extract<ExtractedParametersFromRpc<IFrameRpcSchema>, {
|
|
61
|
+
method: TParameters["method"];
|
|
62
|
+
}>>>;
|
|
63
|
+
/**
|
|
64
|
+
* Get the right response key provider for the given param
|
|
65
|
+
* @param param
|
|
66
|
+
*/
|
|
67
|
+
declare function getIFrameResponseKeyProvider<TParameters extends Pick<ExtractedParametersFromRpc<IFrameRpcSchema>, "method">>(param: TParameters): RpcResponseKeyProvider<TParameters>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the right request key provider for the given args
|
|
71
|
+
* @param args
|
|
72
|
+
*/
|
|
73
|
+
declare const redirectRequestKeyProvider: KeyProvider<ExtractedParametersFromRpc<RedirectRpcSchema>>;
|
|
74
|
+
type RedirectRpcResponseKeyProvider<TMethod extends ExtractedParametersFromRpc<RedirectRpcSchema>["method"]> = KeyProvider<Extract<RedirectRpcSchema[number], {
|
|
75
|
+
Method: TMethod;
|
|
76
|
+
}>["ReturnType"]>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the right response key provider for the given redirect method
|
|
79
|
+
* @param method
|
|
80
|
+
*/
|
|
81
|
+
declare function getRedirectResponseResponseKeyProvider<TMethod extends ExtractedParametersFromRpc<RedirectRpcSchema>["method"]>(method: TMethod): RedirectRpcResponseKeyProvider<TMethod>;
|
|
82
|
+
|
|
83
|
+
export { type CompressedData, ExtractedParametersFromRpc, ExtractedReturnTypeFromRpc, FrakClient, FrakWalletSdkConfig, type HashProtectedData, IFrameRpcSchema, type KeyProvider, RedirectRpcSchema, createIFrameFrakClient, createIframe, decompressDataAndCheckHash, getIFrameResponseKeyProvider, getRedirectResponseResponseKeyProvider, hashAndCompressData, iFrameRequestKeyProvider, redirectRequestKeyProvider };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { a as FrakWalletSdkConfig, F as FrakClient, E as ExtractedParametersFromRpc, I as IFrameRpcSchema, c as ExtractedReturnTypeFromRpc, R as RedirectRpcSchema } from '../client-SCwoh_kP.js';
|
|
2
|
+
export { A as ArticleUnlockStatusReturnType, f as IFrameEvent, e as IFrameRpcEvent, d as IFrameTransport, P as PaidArticleUnlockPrice, b as StartArticleUnlockParams, S as StartArticleUnlockReturnType, U as UnlockOptionsReturnType, W as WalletStatusReturnType } from '../client-SCwoh_kP.js';
|
|
3
|
+
import 'viem';
|
|
4
|
+
import 'viem/chains';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a new iframe Frak client
|
|
8
|
+
*/
|
|
9
|
+
declare function createIFrameFrakClient({ config, iframe, }: {
|
|
10
|
+
config: FrakWalletSdkConfig;
|
|
11
|
+
iframe: HTMLIFrameElement;
|
|
12
|
+
}): FrakClient;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create the given iframe
|
|
16
|
+
* @param walletBaseUrl
|
|
17
|
+
*/
|
|
18
|
+
declare function createIframe({ walletBaseUrl, }: {
|
|
19
|
+
walletBaseUrl: string;
|
|
20
|
+
}): Promise<HTMLIFrameElement | undefined>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The received encoded data from a client
|
|
24
|
+
* -> The encoded should contain a HashProtectedData once decoded
|
|
25
|
+
*/
|
|
26
|
+
type CompressedData = Readonly<{
|
|
27
|
+
compressed: string;
|
|
28
|
+
compressedHash: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* The encoded data to send to a client / received by a client
|
|
32
|
+
*/
|
|
33
|
+
type HashProtectedData<DataType> = Readonly<DataType & {
|
|
34
|
+
validationHash: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Represent a key provider used for the hashed and secure compression
|
|
38
|
+
*/
|
|
39
|
+
type KeyProvider<DataType> = (value: DataType) => string[];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Compress the given params, and add hash protection to (rapidly) prevent interception modification
|
|
43
|
+
* @param data The params to encode
|
|
44
|
+
* @param keyProvider The method used to access the keys
|
|
45
|
+
*/
|
|
46
|
+
declare function hashAndCompressData<T>(data: T, keyProvider: KeyProvider<T>): Promise<CompressedData>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Decompress the given string
|
|
50
|
+
* @param compressedData The params to encode
|
|
51
|
+
* @param keyAccessor The key accessor used to query the keys used for the validation hash
|
|
52
|
+
*/
|
|
53
|
+
declare function decompressDataAndCheckHash<T>(compressedData: CompressedData, keyAccessor: KeyProvider<T>): Promise<HashProtectedData<T>>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the right request key provider for the given args
|
|
57
|
+
* @param args
|
|
58
|
+
*/
|
|
59
|
+
declare const iFrameRequestKeyProvider: KeyProvider<ExtractedParametersFromRpc<IFrameRpcSchema>>;
|
|
60
|
+
type RpcResponseKeyProvider<TParameters extends Pick<ExtractedParametersFromRpc<IFrameRpcSchema>, "method">> = KeyProvider<ExtractedReturnTypeFromRpc<IFrameRpcSchema, Extract<ExtractedParametersFromRpc<IFrameRpcSchema>, {
|
|
61
|
+
method: TParameters["method"];
|
|
62
|
+
}>>>;
|
|
63
|
+
/**
|
|
64
|
+
* Get the right response key provider for the given param
|
|
65
|
+
* @param param
|
|
66
|
+
*/
|
|
67
|
+
declare function getIFrameResponseKeyProvider<TParameters extends Pick<ExtractedParametersFromRpc<IFrameRpcSchema>, "method">>(param: TParameters): RpcResponseKeyProvider<TParameters>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the right request key provider for the given args
|
|
71
|
+
* @param args
|
|
72
|
+
*/
|
|
73
|
+
declare const redirectRequestKeyProvider: KeyProvider<ExtractedParametersFromRpc<RedirectRpcSchema>>;
|
|
74
|
+
type RedirectRpcResponseKeyProvider<TMethod extends ExtractedParametersFromRpc<RedirectRpcSchema>["method"]> = KeyProvider<Extract<RedirectRpcSchema[number], {
|
|
75
|
+
Method: TMethod;
|
|
76
|
+
}>["ReturnType"]>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the right response key provider for the given redirect method
|
|
79
|
+
* @param method
|
|
80
|
+
*/
|
|
81
|
+
declare function getRedirectResponseResponseKeyProvider<TMethod extends ExtractedParametersFromRpc<RedirectRpcSchema>["method"]>(method: TMethod): RedirectRpcResponseKeyProvider<TMethod>;
|
|
82
|
+
|
|
83
|
+
export { type CompressedData, ExtractedParametersFromRpc, ExtractedReturnTypeFromRpc, FrakClient, FrakWalletSdkConfig, type HashProtectedData, IFrameRpcSchema, type KeyProvider, RedirectRpcSchema, createIFrameFrakClient, createIframe, decompressDataAndCheckHash, getIFrameResponseKeyProvider, getRedirectResponseResponseKeyProvider, hashAndCompressData, iFrameRequestKeyProvider, redirectRequestKeyProvider };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField,
|
|
3
|
+
createIframe,
|
|
4
|
+
decompressDataAndCheckHash,
|
|
5
|
+
getIFrameResponseKeyProvider,
|
|
6
|
+
getRedirectResponseResponseKeyProvider,
|
|
7
|
+
hashAndCompressData,
|
|
8
|
+
iFrameRequestKeyProvider,
|
|
9
|
+
redirectRequestKeyProvider
|
|
10
|
+
} from "../chunk-JE64MPH2.js";
|
|
11
|
+
|
|
12
|
+
// src/core/utils/Deferred.ts
|
|
13
|
+
var Deferred = class {
|
|
14
|
+
constructor() {
|
|
15
|
+
__publicField(this, "_promise");
|
|
16
|
+
__publicField(this, "_resolve");
|
|
17
|
+
__publicField(this, "_reject");
|
|
18
|
+
__publicField(this, "resolve", (value) => {
|
|
19
|
+
this._resolve?.(value);
|
|
20
|
+
});
|
|
21
|
+
__publicField(this, "reject", (reason) => {
|
|
22
|
+
this._reject?.(reason);
|
|
23
|
+
});
|
|
24
|
+
this._promise = new Promise((resolve, reject) => {
|
|
25
|
+
this._resolve = resolve;
|
|
26
|
+
this._reject = reject;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
get promise() {
|
|
30
|
+
return this._promise;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/core/clients/transports/iframeChannelManager.ts
|
|
35
|
+
function createIFrameChannelManager() {
|
|
36
|
+
const channels = /* @__PURE__ */ new Map();
|
|
37
|
+
return {
|
|
38
|
+
// TODO: Better id system?? uid stuff?
|
|
39
|
+
createChannel: (resolver) => {
|
|
40
|
+
const id = Math.random().toString(36).substring(7);
|
|
41
|
+
channels.set(id, resolver);
|
|
42
|
+
return id;
|
|
43
|
+
},
|
|
44
|
+
getRpcResolver: (id) => channels.get(id),
|
|
45
|
+
removeChannel: (id) => channels.delete(id),
|
|
46
|
+
destroy: () => channels.clear()
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/core/clients/transports/iframeMessageHandler.ts
|
|
51
|
+
function createIFrameMessageHandler({
|
|
52
|
+
frakWalletUrl,
|
|
53
|
+
iframe,
|
|
54
|
+
channelManager
|
|
55
|
+
}) {
|
|
56
|
+
if (typeof window === "undefined") {
|
|
57
|
+
throw new Error("iframe client should be used in the browser");
|
|
58
|
+
}
|
|
59
|
+
if (!iframe.contentWindow) {
|
|
60
|
+
throw new Error("The iframe does not have a content window");
|
|
61
|
+
}
|
|
62
|
+
const contentWindow = iframe.contentWindow;
|
|
63
|
+
const isConnected = new Deferred();
|
|
64
|
+
const msgHandler = async (event) => {
|
|
65
|
+
if (!event.origin) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (new URL(event.origin).origin.toLowerCase() !== new URL(frakWalletUrl).origin.toLowerCase()) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if ("lifecycle" in event.data) {
|
|
72
|
+
isConnected.resolve(event.data.lifecycle === "connected");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const channel = event.data.id;
|
|
76
|
+
const resolver = channelManager.getRpcResolver(channel);
|
|
77
|
+
if (!resolver) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await resolver(event.data);
|
|
81
|
+
};
|
|
82
|
+
window.addEventListener("message", msgHandler);
|
|
83
|
+
const sendEvent = (message) => {
|
|
84
|
+
contentWindow.postMessage(message, {
|
|
85
|
+
targetOrigin: frakWalletUrl
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
const cleanup = () => {
|
|
89
|
+
window.removeEventListener("message", msgHandler);
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
isConnected: isConnected.promise,
|
|
93
|
+
sendEvent,
|
|
94
|
+
cleanup
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/core/clients/createIFrameFrakClient.ts
|
|
99
|
+
function createIFrameFrakClient({
|
|
100
|
+
config,
|
|
101
|
+
iframe
|
|
102
|
+
}) {
|
|
103
|
+
const channelManager = createIFrameChannelManager();
|
|
104
|
+
const messageHandler = createIFrameMessageHandler({
|
|
105
|
+
frakWalletUrl: config.walletUrl,
|
|
106
|
+
iframe,
|
|
107
|
+
channelManager
|
|
108
|
+
});
|
|
109
|
+
const request = async (args) => {
|
|
110
|
+
const isConnected = await messageHandler.isConnected;
|
|
111
|
+
if (!isConnected) {
|
|
112
|
+
throw new Error("The iframe provider isn't connected yet");
|
|
113
|
+
}
|
|
114
|
+
const result = new Deferred();
|
|
115
|
+
const resultCompressionKeyProvider = getIFrameResponseKeyProvider(args);
|
|
116
|
+
const channelId = channelManager.createChannel(async (message) => {
|
|
117
|
+
const decompressed = await decompressDataAndCheckHash(
|
|
118
|
+
message.data,
|
|
119
|
+
resultCompressionKeyProvider
|
|
120
|
+
);
|
|
121
|
+
result.resolve(decompressed);
|
|
122
|
+
channelManager.removeChannel(channelId);
|
|
123
|
+
});
|
|
124
|
+
const compressedMessage = await hashAndCompressData(
|
|
125
|
+
args,
|
|
126
|
+
iFrameRequestKeyProvider
|
|
127
|
+
);
|
|
128
|
+
messageHandler.sendEvent({
|
|
129
|
+
id: channelId,
|
|
130
|
+
topic: args.method,
|
|
131
|
+
data: compressedMessage
|
|
132
|
+
});
|
|
133
|
+
return result.promise;
|
|
134
|
+
};
|
|
135
|
+
const listenerRequest = async (args, callback) => {
|
|
136
|
+
const isConnected = await messageHandler.isConnected;
|
|
137
|
+
if (!isConnected) {
|
|
138
|
+
throw new Error("The iframe provider isn't connected yet");
|
|
139
|
+
}
|
|
140
|
+
const resultCompressionKeyProvider = getIFrameResponseKeyProvider(args);
|
|
141
|
+
const channelId = channelManager.createChannel(async (message) => {
|
|
142
|
+
const decompressed = await decompressDataAndCheckHash(
|
|
143
|
+
message.data,
|
|
144
|
+
resultCompressionKeyProvider
|
|
145
|
+
);
|
|
146
|
+
callback(decompressed);
|
|
147
|
+
});
|
|
148
|
+
const compressedMessage = await hashAndCompressData(
|
|
149
|
+
args,
|
|
150
|
+
iFrameRequestKeyProvider
|
|
151
|
+
);
|
|
152
|
+
messageHandler.sendEvent({
|
|
153
|
+
id: channelId,
|
|
154
|
+
topic: args.method,
|
|
155
|
+
data: compressedMessage
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
const destroy = async () => {
|
|
159
|
+
channelManager.destroy();
|
|
160
|
+
messageHandler.cleanup();
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
config,
|
|
164
|
+
waitForConnection: messageHandler.isConnected,
|
|
165
|
+
request,
|
|
166
|
+
listenerRequest,
|
|
167
|
+
destroy
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
export {
|
|
171
|
+
createIFrameFrakClient,
|
|
172
|
+
createIframe,
|
|
173
|
+
decompressDataAndCheckHash,
|
|
174
|
+
getIFrameResponseKeyProvider,
|
|
175
|
+
getRedirectResponseResponseKeyProvider,
|
|
176
|
+
hashAndCompressData,
|
|
177
|
+
iFrameRequestKeyProvider,
|
|
178
|
+
redirectRequestKeyProvider
|
|
179
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
package/dist/index.d.cts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@frak-labs/nexus-sdk",
|
|
3
|
+
"author": "Frak Labs",
|
|
4
|
+
"version": "0.0.1-alpha",
|
|
5
|
+
"description": "Nexus Wallet client SDK, helping any person to interact with the Frak wallet, and require the unlock of a premium article within the Frak ecosystem.",
|
|
6
|
+
"repository": "https://github.com/frak-id/wallet",
|
|
7
|
+
"homepage": "https://docs.frak.id/wallet-sdk",
|
|
8
|
+
"license": "GNU GPL 3.0",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"private": false,
|
|
11
|
+
"main": "dist/index.cjs",
|
|
12
|
+
"module": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"typings": "dist/index.d.ts",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"files": [
|
|
17
|
+
"/dist"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"default": "./dist/index.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./core": {
|
|
26
|
+
"types": "./dist/core/index.d.ts",
|
|
27
|
+
"import": "./dist/core/index.js",
|
|
28
|
+
"default": "./dist/core/index.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./actions": {
|
|
31
|
+
"types": "./dist/core/actions/index.d.ts",
|
|
32
|
+
"import": "./dist/core/actions/index.js",
|
|
33
|
+
"default": "./dist/core/actions/index.cjs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"lint": "biome lint .",
|
|
38
|
+
"format:check": "biome check .",
|
|
39
|
+
"format": "biome check --apply .",
|
|
40
|
+
"clean": "rimraf dist",
|
|
41
|
+
"build": "tsup --splitting"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"viem": "^2.7.10"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"async-lz-string": "^1.1.0",
|
|
48
|
+
"js-sha256": "^0.11.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^20",
|
|
52
|
+
"tsup": "^8.0.2",
|
|
53
|
+
"typescript": "^5"
|
|
54
|
+
}
|
|
55
|
+
}
|