@gibs/common 1.13.1 → 1.17.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/README.md +34 -4
- package/cache/package.json +6 -0
- package/client/package.json +6 -0
- package/dist/cache.d.ts +25 -0
- package/dist/cache.js +27 -0
- package/dist/cjs/assert.d.ts +18 -0
- package/dist/cjs/assert.js +31 -0
- package/dist/cjs/cache.d.ts +39 -0
- package/dist/cjs/cache.js +77 -0
- package/dist/cjs/client.d.ts +48 -0
- package/dist/cjs/client.js +171 -0
- package/dist/cjs/erc20.d.ts +18 -0
- package/dist/cjs/erc20.js +39 -0
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.js +24 -0
- package/dist/cjs/multicall.d.ts +56 -0
- package/dist/cjs/multicall.js +217 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/rpcPacer.d.ts +88 -0
- package/dist/cjs/rpcPacer.js +158 -0
- package/dist/cjs/serialize.d.ts +19 -0
- package/dist/cjs/serialize.js +48 -0
- package/dist/cjs/types.d.ts +11 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/url.d.ts +110 -0
- package/dist/cjs/url.js +292 -0
- package/dist/client.js +2 -1
- package/dist/erc20.d.ts +3 -5
- package/dist/erc20.js +5 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/multicall.js +1 -2
- package/dist/url.d.ts +110 -0
- package/dist/url.js +281 -0
- package/erc20/package.json +6 -0
- package/llms.txt +24 -5
- package/multicall/package.json +6 -0
- package/package.json +204 -8
- package/serialize/package.json +6 -0
- package/types/package.json +6 -0
- package/url/package.json +6 -0
package/dist/url.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request addresses, built and read with plain string work.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS: React Native 0.77 installs its own `URL` and
|
|
5
|
+
* `URLSearchParams` (react-native/Libraries/Blob/URL.js), and both are partial.
|
|
6
|
+
* `new URL(x).protocol`, `.host`, `.pathname` and `.search` throw "not
|
|
7
|
+
* implemented". `searchParams` is always a new, empty list, so a reader of it
|
|
8
|
+
* silently sees no parameters. `URLSearchParams` can only append and
|
|
9
|
+
* serialize: `get`, `set`, `has` and `delete` throw, and a string passed to
|
|
10
|
+
* its constructor is ignored. A package that uses either class needs a
|
|
11
|
+
* polyfill in a wallet. These functions need nothing from the runtime but
|
|
12
|
+
* `encodeURIComponent` and `decodeURIComponent`.
|
|
13
|
+
*
|
|
14
|
+
* Their output matches what the WHATWG classes produce for the addresses the
|
|
15
|
+
* Gibs packages build: a lowercase `http:` or `https:` origin with a plain
|
|
16
|
+
* path. A query is encoded exactly as `URLSearchParams` encodes it, as
|
|
17
|
+
* `application/x-www-form-urlencoded`: a space becomes `+`, and only letters,
|
|
18
|
+
* digits and `*-._` stay as they are. They do not normalize the address
|
|
19
|
+
* itself: an uppercase host or a `..` path segment passes through as written.
|
|
20
|
+
*/
|
|
21
|
+
/** A surrogate pair, or a lone surrogate half. */
|
|
22
|
+
const surrogates = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g;
|
|
23
|
+
/** The characters `encodeURIComponent` keeps that a form encoder escapes. */
|
|
24
|
+
const formEscapedCharacters = /[!'()~]/g;
|
|
25
|
+
/** A run of percent-encoded bytes. */
|
|
26
|
+
const percentEncodedRun = /(?:%[0-9A-Fa-f]{2})+/g;
|
|
27
|
+
/** The port each special scheme leaves out of its host. */
|
|
28
|
+
const defaultPorts = Object.freeze({
|
|
29
|
+
http: '80',
|
|
30
|
+
https: '443',
|
|
31
|
+
ws: '80',
|
|
32
|
+
wss: '443',
|
|
33
|
+
ftp: '21',
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Replaces each lone surrogate half with U+FFFD, as the WHATWG classes do
|
|
37
|
+
* before they encode. `encodeURIComponent` would throw on one instead.
|
|
38
|
+
*
|
|
39
|
+
* @param text - any string
|
|
40
|
+
* @returns the string, well formed
|
|
41
|
+
*/
|
|
42
|
+
const toWellFormed = (text) => text.replace(surrogates, (match) => (match.length === 2 ? match : '�'));
|
|
43
|
+
/**
|
|
44
|
+
* Percent-encodes one character as two uppercase hex digits.
|
|
45
|
+
*
|
|
46
|
+
* @param character - a single ASCII character
|
|
47
|
+
* @returns the character as `%XX`
|
|
48
|
+
*/
|
|
49
|
+
const percentEncodeCharacter = (character) => `%${character.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0')}`;
|
|
50
|
+
/**
|
|
51
|
+
* Encodes a query name or value exactly as `URLSearchParams.toString` does.
|
|
52
|
+
*
|
|
53
|
+
* @param text - the raw name or value
|
|
54
|
+
* @returns the encoded text
|
|
55
|
+
*/
|
|
56
|
+
export const encodeQueryComponent = (text) => encodeURIComponent(toWellFormed(text))
|
|
57
|
+
.replace(formEscapedCharacters, percentEncodeCharacter)
|
|
58
|
+
.replace(/%20/g, '+');
|
|
59
|
+
/**
|
|
60
|
+
* Counts the continuation bytes a UTF-8 lead byte announces, and the bounds
|
|
61
|
+
* the first of them must fall in. The bounds reject overlong forms and
|
|
62
|
+
* surrogates, as the WHATWG decoder does.
|
|
63
|
+
*
|
|
64
|
+
* @param lead - the first byte of a sequence
|
|
65
|
+
* @returns the count, the lead byte's own bits, and the first continuation byte's bounds; null for a byte that cannot start one
|
|
66
|
+
*/
|
|
67
|
+
const utf8Lead = (lead) => {
|
|
68
|
+
if (lead >= 0xc2 && lead <= 0xdf)
|
|
69
|
+
return { count: 1, bits: lead & 0x1f, lower: 0x80, upper: 0xbf };
|
|
70
|
+
if (lead === 0xe0)
|
|
71
|
+
return { count: 2, bits: lead & 0x0f, lower: 0xa0, upper: 0xbf };
|
|
72
|
+
if (lead === 0xed)
|
|
73
|
+
return { count: 2, bits: lead & 0x0f, lower: 0x80, upper: 0x9f };
|
|
74
|
+
if (lead >= 0xe1 && lead <= 0xef)
|
|
75
|
+
return { count: 2, bits: lead & 0x0f, lower: 0x80, upper: 0xbf };
|
|
76
|
+
if (lead === 0xf0)
|
|
77
|
+
return { count: 3, bits: lead & 0x07, lower: 0x90, upper: 0xbf };
|
|
78
|
+
if (lead === 0xf4)
|
|
79
|
+
return { count: 3, bits: lead & 0x07, lower: 0x80, upper: 0x8f };
|
|
80
|
+
if (lead >= 0xf1 && lead <= 0xf3)
|
|
81
|
+
return { count: 3, bits: lead & 0x07, lower: 0x80, upper: 0xbf };
|
|
82
|
+
return null;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Decodes UTF-8 bytes as the WHATWG decoder does: each malformed part becomes
|
|
86
|
+
* one U+FFFD, and a byte that ends a malformed part is read again as the
|
|
87
|
+
* start of the next. Only reached when `decodeURIComponent` refuses a run.
|
|
88
|
+
*
|
|
89
|
+
* @param bytes - the bytes
|
|
90
|
+
* @returns the decoded text
|
|
91
|
+
*/
|
|
92
|
+
const decodeUtf8Leniently = (bytes) => {
|
|
93
|
+
const decode = (index, decoded) => {
|
|
94
|
+
if (index >= bytes.length)
|
|
95
|
+
return decoded;
|
|
96
|
+
const lead = bytes[index];
|
|
97
|
+
if (lead < 0x80)
|
|
98
|
+
return decode(index + 1, decoded + String.fromCharCode(lead));
|
|
99
|
+
const shape = utf8Lead(lead);
|
|
100
|
+
if (shape === null)
|
|
101
|
+
return decode(index + 1, `${decoded}�`);
|
|
102
|
+
const readContinuation = (offset, codePoint) => {
|
|
103
|
+
if (offset > shape.count)
|
|
104
|
+
return { codePoint, length: offset };
|
|
105
|
+
const byte = bytes[index + offset];
|
|
106
|
+
const lower = offset === 1 ? shape.lower : 0x80;
|
|
107
|
+
const upper = offset === 1 ? shape.upper : 0xbf;
|
|
108
|
+
if (byte === undefined || byte < lower || byte > upper)
|
|
109
|
+
return { codePoint: -1, length: offset };
|
|
110
|
+
return readContinuation(offset + 1, (codePoint << 6) | (byte & 0x3f));
|
|
111
|
+
};
|
|
112
|
+
const { codePoint, length } = readContinuation(1, shape.bits);
|
|
113
|
+
if (codePoint === -1)
|
|
114
|
+
return decode(index + length, `${decoded}�`);
|
|
115
|
+
return decode(index + length, decoded + String.fromCodePoint(codePoint));
|
|
116
|
+
};
|
|
117
|
+
return decode(0, '');
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Decodes one run of `%XX` bytes.
|
|
121
|
+
*
|
|
122
|
+
* @param run - consecutive `%XX` sequences
|
|
123
|
+
* @returns the text they encode
|
|
124
|
+
*/
|
|
125
|
+
const decodePercentRun = (run) => {
|
|
126
|
+
try {
|
|
127
|
+
return decodeURIComponent(run);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return decodeUtf8Leniently(run.slice(1).split('%').map((pair) => Number.parseInt(pair, 16)));
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Decodes a query name or value as the WHATWG URL standard says
|
|
135
|
+
* `URLSearchParams` must: `+` is a space, a valid `%XX` is a byte, a `%` that
|
|
136
|
+
* starts no valid sequence stays as it is, and each malformed UTF-8 part, or
|
|
137
|
+
* lone surrogate half, becomes U+FFFD.
|
|
138
|
+
*
|
|
139
|
+
* @param text - the encoded name or value
|
|
140
|
+
* @returns the decoded text
|
|
141
|
+
*/
|
|
142
|
+
export const decodeQueryComponent = (text) => toWellFormed(text).replace(/\+/g, ' ').replace(percentEncodedRun, decodePercentRun);
|
|
143
|
+
/**
|
|
144
|
+
* Lists the parameters of a query, decoded and in order.
|
|
145
|
+
*
|
|
146
|
+
* @param query - a query, with or without its leading `?`
|
|
147
|
+
* @returns each parameter's name and value; a parameter with no `=` has an empty value
|
|
148
|
+
*/
|
|
149
|
+
export const parseQuery = (query) => query
|
|
150
|
+
.replace(/^\?/, '')
|
|
151
|
+
.split('&')
|
|
152
|
+
.filter((part) => part !== '')
|
|
153
|
+
.map((part) => {
|
|
154
|
+
const equalsAt = part.indexOf('=');
|
|
155
|
+
const name = equalsAt === -1 ? part : part.slice(0, equalsAt);
|
|
156
|
+
const value = equalsAt === -1 ? '' : part.slice(equalsAt + 1);
|
|
157
|
+
return [decodeQueryComponent(name), decodeQueryComponent(value)];
|
|
158
|
+
});
|
|
159
|
+
/**
|
|
160
|
+
* Turns query parameters into ordered pairs.
|
|
161
|
+
*
|
|
162
|
+
* @param parameters - a record or pairs; see {@link QueryParameters}
|
|
163
|
+
* @returns the pairs, with every `undefined` record value left out
|
|
164
|
+
*/
|
|
165
|
+
const toEntries = (parameters) => {
|
|
166
|
+
if (Array.isArray(parameters))
|
|
167
|
+
return parameters;
|
|
168
|
+
return Object.entries(parameters).filter((entry) => entry[1] !== undefined);
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Writes a query, as `new URLSearchParams(parameters).toString()` does.
|
|
172
|
+
*
|
|
173
|
+
* @param parameters - a record or pairs; see {@link QueryParameters}
|
|
174
|
+
* @returns the encoded query, with no leading `?`; empty for no parameters
|
|
175
|
+
*/
|
|
176
|
+
export const buildQuery = (parameters) => toEntries(parameters)
|
|
177
|
+
.map(([name, value]) => `${encodeQueryComponent(name)}=${encodeQueryComponent(value)}`)
|
|
178
|
+
.join('&');
|
|
179
|
+
/**
|
|
180
|
+
* Sets one parameter in a query, as `URLSearchParams.set` does: the first
|
|
181
|
+
* parameter of that name takes the value and any later ones are removed, or
|
|
182
|
+
* the parameter is appended when none has the name.
|
|
183
|
+
*
|
|
184
|
+
* @param query - an encoded query, with or without its leading `?`
|
|
185
|
+
* @param name - the parameter's name
|
|
186
|
+
* @param value - its value
|
|
187
|
+
* @returns the encoded query, with no leading `?`
|
|
188
|
+
*/
|
|
189
|
+
export const setQueryParameter = (query, name, value) => {
|
|
190
|
+
const entries = parseQuery(query);
|
|
191
|
+
const firstAt = entries.findIndex(([entryName]) => entryName === name);
|
|
192
|
+
if (firstAt === -1)
|
|
193
|
+
return buildQuery([...entries, [name, value]]);
|
|
194
|
+
return buildQuery(entries.flatMap((entry, index) => {
|
|
195
|
+
if (index === firstAt)
|
|
196
|
+
return [[name, value]];
|
|
197
|
+
return entry[0] === name ? [] : [entry];
|
|
198
|
+
}));
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Splits an address at its first `#` and then at its first `?`.
|
|
202
|
+
*
|
|
203
|
+
* @param address - any address
|
|
204
|
+
* @returns everything before the query, the query and the fragment, each without its delimiter
|
|
205
|
+
*/
|
|
206
|
+
const splitAtQuery = (address) => {
|
|
207
|
+
const fragmentAt = address.indexOf('#');
|
|
208
|
+
const beforeFragment = fragmentAt === -1 ? address : address.slice(0, fragmentAt);
|
|
209
|
+
const fragment = fragmentAt === -1 ? '' : address.slice(fragmentAt + 1);
|
|
210
|
+
const queryAt = beforeFragment.indexOf('?');
|
|
211
|
+
if (queryAt === -1)
|
|
212
|
+
return { beforeQuery: beforeFragment, query: '', fragment };
|
|
213
|
+
return { beforeQuery: beforeFragment.slice(0, queryAt), query: beforeFragment.slice(queryAt + 1), fragment };
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Adds query parameters to an address, as `url.searchParams.set` does for
|
|
217
|
+
* each one in turn. A query already on the address is kept, and a fragment
|
|
218
|
+
* stays at the end.
|
|
219
|
+
*
|
|
220
|
+
* @param address - the address, with or without a query
|
|
221
|
+
* @param parameters - a record or pairs; see {@link QueryParameters}
|
|
222
|
+
* @returns the address with the parameters set; the address unchanged when there are none
|
|
223
|
+
*/
|
|
224
|
+
export const buildUrl = (address, parameters) => {
|
|
225
|
+
const entries = toEntries(parameters);
|
|
226
|
+
if (entries.length === 0)
|
|
227
|
+
return address;
|
|
228
|
+
const { beforeQuery, query, fragment } = splitAtQuery(address);
|
|
229
|
+
const updated = entries.reduce((current, [name, value]) => setQueryParameter(current, name, value), query);
|
|
230
|
+
return `${beforeQuery}?${updated}${fragment === '' ? '' : `#${fragment}`}`;
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* Reads the host the WHATWG `URL` reports from an authority: lowercase, with
|
|
234
|
+
* any user name and password dropped, and the port dropped when it is the
|
|
235
|
+
* scheme's default.
|
|
236
|
+
*
|
|
237
|
+
* @param authority - the text between `//` and the path
|
|
238
|
+
* @param scheme - the lowercase scheme
|
|
239
|
+
* @returns the host
|
|
240
|
+
*/
|
|
241
|
+
const hostOfAuthority = (authority, scheme) => {
|
|
242
|
+
const hostAndPort = authority.slice(authority.lastIndexOf('@') + 1).toLowerCase();
|
|
243
|
+
const port = /:(\d*)$/.exec(hostAndPort);
|
|
244
|
+
if (port === null)
|
|
245
|
+
return hostAndPort;
|
|
246
|
+
const hostname = hostAndPort.slice(0, port.index);
|
|
247
|
+
if (port[1] === '')
|
|
248
|
+
return hostname;
|
|
249
|
+
const portNumber = String(Number(port[1]));
|
|
250
|
+
return portNumber === defaultPorts[scheme] ? hostname : `${hostname}:${portNumber}`;
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Splits an address into its parts, without the WHATWG `URL` class.
|
|
254
|
+
*
|
|
255
|
+
* @param address - any address; leading and trailing spaces and control characters are ignored, as the WHATWG parser ignores them
|
|
256
|
+
* @returns the parts; see {@link UrlParts}
|
|
257
|
+
*/
|
|
258
|
+
export const splitUrl = (address) => {
|
|
259
|
+
const trimmed = address.replace(/^[\u0000- ]+|[\u0000- ]+$/g, '');
|
|
260
|
+
const { beforeQuery, query, fragment } = splitAtQuery(trimmed);
|
|
261
|
+
const schemeMatch = /^([A-Za-z][A-Za-z0-9+.-]*):/.exec(beforeQuery);
|
|
262
|
+
const scheme = schemeMatch === null ? '' : schemeMatch[1].toLowerCase();
|
|
263
|
+
const rest = schemeMatch === null ? beforeQuery : beforeQuery.slice(schemeMatch[0].length);
|
|
264
|
+
if (!rest.startsWith('//'))
|
|
265
|
+
return { scheme, host: '', path: rest, query, fragment };
|
|
266
|
+
const pathAt = rest.indexOf('/', 2);
|
|
267
|
+
const authority = pathAt === -1 ? rest.slice(2) : rest.slice(2, pathAt);
|
|
268
|
+
const path = pathAt === -1 ? '/' : rest.slice(pathAt);
|
|
269
|
+
return { scheme, host: hostOfAuthority(authority, scheme), path, query, fragment };
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Says whether a value is an absolute `http:` or `https:` address with a host.
|
|
273
|
+
* It reads the scheme by its prefix, so it needs no `URL` class.
|
|
274
|
+
*
|
|
275
|
+
* @param value - any string
|
|
276
|
+
* @returns true for an absolute `http:` or `https:` address
|
|
277
|
+
*/
|
|
278
|
+
export const isHttpUrl = (value) => {
|
|
279
|
+
const { scheme, host } = splitUrl(value);
|
|
280
|
+
return (scheme === 'http' || scheme === 'https') && host !== '';
|
|
281
|
+
};
|
package/llms.txt
CHANGED
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
10
10
|
- Run `npm install @gibs/common viem`.
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
11
|
+
- It runs on Node 20 or later, in browsers, and in React Native under Hermes.
|
|
12
|
+
- `import` loads the ECMAScript module build (`dist/`). `require` loads the CommonJS build (`dist/cjs/`).
|
|
13
|
+
- React Native 0.77 or later: Metro's default configuration and the React Native jest preset load it with no extra setup. Add no `resolveRequest` hook and no `transformIgnorePatterns`. The `react-native` condition gives an `import` statement the ECMAScript module build and a `require` call the CommonJS build.
|
|
14
|
+
- It needs no polyfill, not even for `URL`: React Native 0.77's own `URL` and `URLSearchParams` are partial, and no entry point reads them.
|
|
15
|
+
- Import from the narrowest subpath, for example `@gibs/common/cache`. Metro does not drop unused exports.
|
|
16
|
+
- It has no runtime dependency except viem.
|
|
17
|
+
- viem is a peer dependency. The range is `>=2.35.0 <3`.
|
|
14
18
|
- Version note: 1.12.0 and older on npm are broken. 1.13.0 is the first usable version.
|
|
15
19
|
|
|
16
20
|
## Entry points
|
|
@@ -19,9 +23,10 @@
|
|
|
19
23
|
- `@gibs/common/client`: `clientFromChain({ chain, urls })`, `chainKey`, `clientCache`.
|
|
20
24
|
- `@gibs/common/erc20`: `multicallErc20`, `erc20MetadataCalls`.
|
|
21
25
|
- `@gibs/common/multicall`: `multicallRead`.
|
|
22
|
-
- `@gibs/common/cache`: `maxMemoize`, `ttlMemoizeSingle`.
|
|
26
|
+
- `@gibs/common/cache`: `maxMemoize`, `ttlMemoizeSingle`, `memoizeByKey`.
|
|
23
27
|
- `@gibs/common/serialize`: `jsonAnyStringify`, `jsonAnyParse`, `isSerializedBigInt`.
|
|
24
28
|
- `@gibs/common/types`: `Call`, `Erc20Metadata`.
|
|
29
|
+
- `@gibs/common/url`: `buildUrl`, `buildQuery`, `parseQuery`, `setQueryParameter`, `splitUrl`, `isHttpUrl`, `encodeQueryComponent`, `decodeQueryComponent`. They build and read request addresses with string work, never with `URL`, and encode a query exactly as `URLSearchParams` does.
|
|
25
30
|
|
|
26
31
|
## Read a token's name, symbol and decimals
|
|
27
32
|
|
|
@@ -56,6 +61,20 @@ const square = maxMemoize((x: number) => x * x, 100)
|
|
|
56
61
|
const price = ttlMemoizeSingle(async (symbol: string) => symbol, 30_000)
|
|
57
62
|
```
|
|
58
63
|
|
|
64
|
+
`memoizeByKey` keys each answer by a resolver you supply, and exposes the
|
|
65
|
+
cache so you can evict one answer or clear them all.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { memoizeByKey } from '@gibs/common/cache'
|
|
69
|
+
|
|
70
|
+
const decimals = memoizeByKey(
|
|
71
|
+
async ({ chainId, address }: { chainId: number; address: string }) => (chainId === 1 ? 6 : 18),
|
|
72
|
+
({ chainId, address }) => `${chainId}-${address.toLowerCase()}`,
|
|
73
|
+
)
|
|
74
|
+
decimals.cache.delete('1-0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48')
|
|
75
|
+
decimals.cache.clear()
|
|
76
|
+
```
|
|
77
|
+
|
|
59
78
|
## Rules
|
|
60
79
|
|
|
61
80
|
- `multicallRead` and `multicallErc20` need a chain object that carries a Multicall3 deployment. A chain without one fails.
|
|
@@ -66,5 +85,5 @@ const price = ttlMemoizeSingle(async (symbol: string) => symbol, 30_000)
|
|
|
66
85
|
|
|
67
86
|
## Links
|
|
68
87
|
|
|
69
|
-
- [README](https://
|
|
88
|
+
- [README](https://www.npmjs.com/package/@gibs/common)
|
|
70
89
|
- [Gibs Finance llms.txt](https://next.gibs.finance/llms.txt): the whole platform.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gibs/common",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Low-level blockchain helpers shared across the Gibs Finance packages: caching, multicall, and serialization.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ethereum",
|
|
@@ -25,48 +25,236 @@
|
|
|
25
25
|
},
|
|
26
26
|
"type": "module",
|
|
27
27
|
"sideEffects": false,
|
|
28
|
-
"main": "./dist/index.js",
|
|
28
|
+
"main": "./dist/cjs/index.js",
|
|
29
|
+
"module": "./dist/index.js",
|
|
30
|
+
"react-native": "./dist/cjs/index.js",
|
|
29
31
|
"types": "./dist/index.d.ts",
|
|
30
32
|
"exports": {
|
|
31
33
|
".": {
|
|
32
34
|
"gibs-source": "./src/index.ts",
|
|
35
|
+
"react-native": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/cjs/index.d.ts",
|
|
42
|
+
"default": "./dist/cjs/index.js"
|
|
43
|
+
},
|
|
44
|
+
"default": {
|
|
45
|
+
"types": "./dist/cjs/index.d.ts",
|
|
46
|
+
"default": "./dist/cjs/index.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"import": {
|
|
50
|
+
"types": "./dist/index.d.ts",
|
|
51
|
+
"default": "./dist/index.js"
|
|
52
|
+
},
|
|
53
|
+
"require": {
|
|
54
|
+
"types": "./dist/cjs/index.d.ts",
|
|
55
|
+
"default": "./dist/cjs/index.js"
|
|
56
|
+
},
|
|
33
57
|
"types": "./dist/index.d.ts",
|
|
34
58
|
"default": "./dist/index.js"
|
|
35
59
|
},
|
|
36
60
|
"./erc20": {
|
|
37
61
|
"gibs-source": "./src/erc20.ts",
|
|
62
|
+
"react-native": {
|
|
63
|
+
"import": {
|
|
64
|
+
"types": "./dist/erc20.d.ts",
|
|
65
|
+
"default": "./dist/erc20.js"
|
|
66
|
+
},
|
|
67
|
+
"require": {
|
|
68
|
+
"types": "./dist/cjs/erc20.d.ts",
|
|
69
|
+
"default": "./dist/cjs/erc20.js"
|
|
70
|
+
},
|
|
71
|
+
"default": {
|
|
72
|
+
"types": "./dist/cjs/erc20.d.ts",
|
|
73
|
+
"default": "./dist/cjs/erc20.js"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"import": {
|
|
77
|
+
"types": "./dist/erc20.d.ts",
|
|
78
|
+
"default": "./dist/erc20.js"
|
|
79
|
+
},
|
|
80
|
+
"require": {
|
|
81
|
+
"types": "./dist/cjs/erc20.d.ts",
|
|
82
|
+
"default": "./dist/cjs/erc20.js"
|
|
83
|
+
},
|
|
38
84
|
"types": "./dist/erc20.d.ts",
|
|
39
85
|
"default": "./dist/erc20.js"
|
|
40
86
|
},
|
|
41
87
|
"./cache": {
|
|
42
88
|
"gibs-source": "./src/cache.ts",
|
|
89
|
+
"react-native": {
|
|
90
|
+
"import": {
|
|
91
|
+
"types": "./dist/cache.d.ts",
|
|
92
|
+
"default": "./dist/cache.js"
|
|
93
|
+
},
|
|
94
|
+
"require": {
|
|
95
|
+
"types": "./dist/cjs/cache.d.ts",
|
|
96
|
+
"default": "./dist/cjs/cache.js"
|
|
97
|
+
},
|
|
98
|
+
"default": {
|
|
99
|
+
"types": "./dist/cjs/cache.d.ts",
|
|
100
|
+
"default": "./dist/cjs/cache.js"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"import": {
|
|
104
|
+
"types": "./dist/cache.d.ts",
|
|
105
|
+
"default": "./dist/cache.js"
|
|
106
|
+
},
|
|
107
|
+
"require": {
|
|
108
|
+
"types": "./dist/cjs/cache.d.ts",
|
|
109
|
+
"default": "./dist/cjs/cache.js"
|
|
110
|
+
},
|
|
43
111
|
"types": "./dist/cache.d.ts",
|
|
44
112
|
"default": "./dist/cache.js"
|
|
45
113
|
},
|
|
46
114
|
"./serialize": {
|
|
47
115
|
"gibs-source": "./src/serialize.ts",
|
|
116
|
+
"react-native": {
|
|
117
|
+
"import": {
|
|
118
|
+
"types": "./dist/serialize.d.ts",
|
|
119
|
+
"default": "./dist/serialize.js"
|
|
120
|
+
},
|
|
121
|
+
"require": {
|
|
122
|
+
"types": "./dist/cjs/serialize.d.ts",
|
|
123
|
+
"default": "./dist/cjs/serialize.js"
|
|
124
|
+
},
|
|
125
|
+
"default": {
|
|
126
|
+
"types": "./dist/cjs/serialize.d.ts",
|
|
127
|
+
"default": "./dist/cjs/serialize.js"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"import": {
|
|
131
|
+
"types": "./dist/serialize.d.ts",
|
|
132
|
+
"default": "./dist/serialize.js"
|
|
133
|
+
},
|
|
134
|
+
"require": {
|
|
135
|
+
"types": "./dist/cjs/serialize.d.ts",
|
|
136
|
+
"default": "./dist/cjs/serialize.js"
|
|
137
|
+
},
|
|
48
138
|
"types": "./dist/serialize.d.ts",
|
|
49
139
|
"default": "./dist/serialize.js"
|
|
50
140
|
},
|
|
51
141
|
"./types": {
|
|
52
142
|
"gibs-source": "./src/types.ts",
|
|
143
|
+
"react-native": {
|
|
144
|
+
"import": {
|
|
145
|
+
"types": "./dist/types.d.ts",
|
|
146
|
+
"default": "./dist/types.js"
|
|
147
|
+
},
|
|
148
|
+
"require": {
|
|
149
|
+
"types": "./dist/cjs/types.d.ts",
|
|
150
|
+
"default": "./dist/cjs/types.js"
|
|
151
|
+
},
|
|
152
|
+
"default": {
|
|
153
|
+
"types": "./dist/cjs/types.d.ts",
|
|
154
|
+
"default": "./dist/cjs/types.js"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"import": {
|
|
158
|
+
"types": "./dist/types.d.ts",
|
|
159
|
+
"default": "./dist/types.js"
|
|
160
|
+
},
|
|
161
|
+
"require": {
|
|
162
|
+
"types": "./dist/cjs/types.d.ts",
|
|
163
|
+
"default": "./dist/cjs/types.js"
|
|
164
|
+
},
|
|
53
165
|
"types": "./dist/types.d.ts",
|
|
54
166
|
"default": "./dist/types.js"
|
|
55
167
|
},
|
|
56
168
|
"./multicall": {
|
|
57
169
|
"gibs-source": "./src/multicall.ts",
|
|
170
|
+
"react-native": {
|
|
171
|
+
"import": {
|
|
172
|
+
"types": "./dist/multicall.d.ts",
|
|
173
|
+
"default": "./dist/multicall.js"
|
|
174
|
+
},
|
|
175
|
+
"require": {
|
|
176
|
+
"types": "./dist/cjs/multicall.d.ts",
|
|
177
|
+
"default": "./dist/cjs/multicall.js"
|
|
178
|
+
},
|
|
179
|
+
"default": {
|
|
180
|
+
"types": "./dist/cjs/multicall.d.ts",
|
|
181
|
+
"default": "./dist/cjs/multicall.js"
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
"import": {
|
|
185
|
+
"types": "./dist/multicall.d.ts",
|
|
186
|
+
"default": "./dist/multicall.js"
|
|
187
|
+
},
|
|
188
|
+
"require": {
|
|
189
|
+
"types": "./dist/cjs/multicall.d.ts",
|
|
190
|
+
"default": "./dist/cjs/multicall.js"
|
|
191
|
+
},
|
|
58
192
|
"types": "./dist/multicall.d.ts",
|
|
59
193
|
"default": "./dist/multicall.js"
|
|
60
194
|
},
|
|
61
195
|
"./client": {
|
|
62
196
|
"gibs-source": "./src/client.ts",
|
|
197
|
+
"react-native": {
|
|
198
|
+
"import": {
|
|
199
|
+
"types": "./dist/client.d.ts",
|
|
200
|
+
"default": "./dist/client.js"
|
|
201
|
+
},
|
|
202
|
+
"require": {
|
|
203
|
+
"types": "./dist/cjs/client.d.ts",
|
|
204
|
+
"default": "./dist/cjs/client.js"
|
|
205
|
+
},
|
|
206
|
+
"default": {
|
|
207
|
+
"types": "./dist/cjs/client.d.ts",
|
|
208
|
+
"default": "./dist/cjs/client.js"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"import": {
|
|
212
|
+
"types": "./dist/client.d.ts",
|
|
213
|
+
"default": "./dist/client.js"
|
|
214
|
+
},
|
|
215
|
+
"require": {
|
|
216
|
+
"types": "./dist/cjs/client.d.ts",
|
|
217
|
+
"default": "./dist/cjs/client.js"
|
|
218
|
+
},
|
|
63
219
|
"types": "./dist/client.d.ts",
|
|
64
220
|
"default": "./dist/client.js"
|
|
65
221
|
},
|
|
222
|
+
"./url": {
|
|
223
|
+
"gibs-source": "./src/url.ts",
|
|
224
|
+
"react-native": {
|
|
225
|
+
"import": {
|
|
226
|
+
"types": "./dist/url.d.ts",
|
|
227
|
+
"default": "./dist/url.js"
|
|
228
|
+
},
|
|
229
|
+
"require": {
|
|
230
|
+
"types": "./dist/cjs/url.d.ts",
|
|
231
|
+
"default": "./dist/cjs/url.js"
|
|
232
|
+
},
|
|
233
|
+
"default": {
|
|
234
|
+
"types": "./dist/cjs/url.d.ts",
|
|
235
|
+
"default": "./dist/cjs/url.js"
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
"import": {
|
|
239
|
+
"types": "./dist/url.d.ts",
|
|
240
|
+
"default": "./dist/url.js"
|
|
241
|
+
},
|
|
242
|
+
"require": {
|
|
243
|
+
"types": "./dist/cjs/url.d.ts",
|
|
244
|
+
"default": "./dist/cjs/url.js"
|
|
245
|
+
},
|
|
246
|
+
"types": "./dist/url.d.ts",
|
|
247
|
+
"default": "./dist/url.js"
|
|
248
|
+
},
|
|
66
249
|
"./test-utils/fuzz": {
|
|
67
250
|
"gibs-source": "./src/test-utils/fuzz.ts",
|
|
68
251
|
"default": "./src/test-utils/fuzz.ts"
|
|
69
|
-
}
|
|
252
|
+
},
|
|
253
|
+
"./test-utils/react-native-url": {
|
|
254
|
+
"gibs-source": "./src/test-utils/react-native-url.ts",
|
|
255
|
+
"default": "./src/test-utils/react-native-url.ts"
|
|
256
|
+
},
|
|
257
|
+
"./package.json": "./package.json"
|
|
70
258
|
},
|
|
71
259
|
"files": [
|
|
72
260
|
"dist",
|
|
@@ -74,20 +262,28 @@
|
|
|
74
262
|
"!dist/**/*.test-d.*",
|
|
75
263
|
"!dist/test-utils",
|
|
76
264
|
"LICENSE",
|
|
77
|
-
"llms.txt"
|
|
265
|
+
"llms.txt",
|
|
266
|
+
"erc20",
|
|
267
|
+
"cache",
|
|
268
|
+
"serialize",
|
|
269
|
+
"types",
|
|
270
|
+
"multicall",
|
|
271
|
+
"client",
|
|
272
|
+
"url"
|
|
78
273
|
],
|
|
79
274
|
"scripts": {
|
|
80
275
|
"prepublishOnly": "npx tsc",
|
|
276
|
+
"prepack": "npm run build:cjs && npm run build:stubs",
|
|
277
|
+
"postpack": "node ../../scripts/subpath-stubs.mjs remove",
|
|
81
278
|
"build": "npx tsc",
|
|
279
|
+
"build:cjs": "node ../../scripts/build-cjs.mjs",
|
|
280
|
+
"build:stubs": "node ../../scripts/subpath-stubs.mjs write",
|
|
82
281
|
"test": "vitest run",
|
|
83
282
|
"test:watch": "vitest",
|
|
84
283
|
"test:coverage": "vitest run --coverage"
|
|
85
284
|
},
|
|
86
|
-
"dependencies": {
|
|
87
|
-
"lodash-es": "^4.17.21"
|
|
88
|
-
},
|
|
89
285
|
"peerDependencies": {
|
|
90
|
-
"viem": ">=2.
|
|
286
|
+
"viem": ">=2.35.0 <3"
|
|
91
287
|
},
|
|
92
288
|
"devDependencies": {
|
|
93
289
|
"@types/node": "^24",
|