@wagmi/connectors 5.0.0 → 5.0.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/dist/esm/coinbaseWallet.js +274 -36
- package/dist/esm/coinbaseWallet.js.map +1 -1
- package/dist/esm/metaMask.js +67 -96
- package/dist/esm/metaMask.js.map +1 -1
- package/dist/esm/safe.js +20 -13
- package/dist/esm/safe.js.map +1 -1
- package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/walletConnect.js +147 -77
- package/dist/esm/walletConnect.js.map +1 -1
- package/dist/types/coinbaseWallet.d.ts +38 -7
- package/dist/types/coinbaseWallet.d.ts.map +1 -1
- package/dist/types/metaMask.d.ts +3 -10
- package/dist/types/metaMask.d.ts.map +1 -1
- package/dist/types/safe.d.ts +2 -2
- package/dist/types/safe.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/walletConnect.d.ts +5 -9
- package/dist/types/walletConnect.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/coinbaseWallet.ts +378 -66
- package/src/metaMask.ts +81 -110
- package/src/safe.ts +29 -14
- package/src/version.ts +1 -1
- package/src/walletConnect.ts +173 -99
- package/dist/esm/exports/index.test-d.js +0 -4
- package/dist/esm/exports/index.test-d.js.map +0 -1
- package/dist/types/exports/index.test-d.d.ts +0 -2
- package/dist/types/exports/index.test-d.d.ts.map +0 -1
package/src/walletConnect.ts
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ChainNotConfiguredError,
|
|
3
|
+
type Connector,
|
|
3
4
|
ProviderNotFoundError,
|
|
4
5
|
createConnector,
|
|
5
|
-
normalizeChainId,
|
|
6
6
|
} from '@wagmi/core'
|
|
7
|
-
import type { Evaluate, ExactPartial, Omit } from '@wagmi/core/internal'
|
|
8
|
-
import { EthereumProvider } from '@walletconnect/ethereum-provider'
|
|
9
7
|
import {
|
|
8
|
+
type Evaluate,
|
|
9
|
+
type ExactPartial,
|
|
10
|
+
type Omit,
|
|
11
|
+
} from '@wagmi/core/internal'
|
|
12
|
+
import { type EthereumProvider } from '@walletconnect/ethereum-provider'
|
|
13
|
+
import {
|
|
14
|
+
type AddEthereumChainParameter,
|
|
10
15
|
type Address,
|
|
11
16
|
type ProviderConnectInfo,
|
|
12
17
|
type ProviderRpcError,
|
|
18
|
+
type RpcError,
|
|
13
19
|
SwitchChainError,
|
|
14
20
|
UserRejectedRequestError,
|
|
15
21
|
getAddress,
|
|
16
22
|
numberToHex,
|
|
17
23
|
} from 'viem'
|
|
18
24
|
|
|
25
|
+
type WalletConnectConnector = Connector & {
|
|
26
|
+
onDisplayUri(uri: string): void
|
|
27
|
+
onSessionDelete(data: { topic: string }): void
|
|
28
|
+
}
|
|
29
|
+
|
|
19
30
|
type EthereumProviderOptions = Parameters<typeof EthereumProvider['init']>[0]
|
|
20
31
|
|
|
21
32
|
export type WalletConnectParameters = Evaluate<
|
|
@@ -26,10 +37,6 @@ export type WalletConnectParameters = Evaluate<
|
|
|
26
37
|
* WalletConnect has yet to establish a relationship with (e.g. the user has not approved or
|
|
27
38
|
* rejected the chain).
|
|
28
39
|
*
|
|
29
|
-
* Preface: Whereas WalletConnect v1 supported dynamic chain switching, WalletConnect v2 requires
|
|
30
|
-
* the user to pre-approve a set of chains up-front. This comes with consequent UX nuances (see below) when
|
|
31
|
-
* a user tries to switch to a chain that they have not approved.
|
|
32
|
-
*
|
|
33
40
|
* This flag mainly affects the behavior when a wallet does not support dynamic chain authorization
|
|
34
41
|
* with WalletConnect v2.
|
|
35
42
|
*
|
|
@@ -41,10 +48,11 @@ export type WalletConnectParameters = Evaluate<
|
|
|
41
48
|
* be a confusing user experience (e.g. the user will not know they have to reconnect
|
|
42
49
|
* unless the dapp handles these types of errors).
|
|
43
50
|
*
|
|
44
|
-
* If `false`, the new chain will be treated as a
|
|
51
|
+
* If `false`, the new chain will be treated as a potentially valid chain. This means that if the user
|
|
45
52
|
* has yet to establish a relationship with the chain in their WalletConnect session, wagmi will successfully
|
|
46
53
|
* auto-connect the user. This comes with the trade-off that the connector will throw an error
|
|
47
|
-
* when attempting to switch to the unapproved chain
|
|
54
|
+
* when attempting to switch to the unapproved chain if the wallet does not support dynamic session updates.
|
|
55
|
+
* This may be useful in cases where a dapp constantly
|
|
48
56
|
* modifies their configured chains, and they do not want to disconnect the user upon
|
|
49
57
|
* auto-connecting. If the user decides to switch to the unapproved chain, it is important that the
|
|
50
58
|
* dapp handles this error and prompts the user to reconnect to the dapp in order to approve
|
|
@@ -72,16 +80,12 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
72
80
|
const isNewChainsStale = parameters.isNewChainsStale ?? true
|
|
73
81
|
|
|
74
82
|
type Provider = Awaited<ReturnType<typeof EthereumProvider['init']>>
|
|
75
|
-
type NamespaceMethods =
|
|
76
|
-
| 'wallet_addEthereumChain'
|
|
77
|
-
| 'wallet_switchEthereumChain'
|
|
78
83
|
type Properties = {
|
|
79
84
|
connect(parameters?: { chainId?: number; pairingTopic?: string }): Promise<{
|
|
80
85
|
accounts: readonly Address[]
|
|
81
86
|
chainId: number
|
|
82
87
|
}>
|
|
83
88
|
getNamespaceChainsIds(): number[]
|
|
84
|
-
getNamespaceMethods(): NamespaceMethods[]
|
|
85
89
|
getRequestedChainsIds(): Promise<number[]>
|
|
86
90
|
isChainsStale(): Promise<boolean>
|
|
87
91
|
onConnect(connectInfo: ProviderConnectInfo): void
|
|
@@ -98,6 +102,13 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
98
102
|
let providerPromise: Promise<typeof provider_>
|
|
99
103
|
const NAMESPACE = 'eip155'
|
|
100
104
|
|
|
105
|
+
let accountsChanged: WalletConnectConnector['onAccountsChanged'] | undefined
|
|
106
|
+
let chainChanged: WalletConnectConnector['onChainChanged'] | undefined
|
|
107
|
+
let connect: WalletConnectConnector['onConnect'] | undefined
|
|
108
|
+
let displayUri: WalletConnectConnector['onDisplayUri'] | undefined
|
|
109
|
+
let sessionDelete: WalletConnectConnector['onSessionDelete'] | undefined
|
|
110
|
+
let disconnect: WalletConnectConnector['onDisconnect'] | undefined
|
|
111
|
+
|
|
101
112
|
return createConnector<Provider, Properties, StorageItem>((config) => ({
|
|
102
113
|
id: 'walletConnect',
|
|
103
114
|
name: 'WalletConnect',
|
|
@@ -105,14 +116,23 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
105
116
|
async setup() {
|
|
106
117
|
const provider = await this.getProvider().catch(() => null)
|
|
107
118
|
if (!provider) return
|
|
108
|
-
|
|
109
|
-
|
|
119
|
+
if (!connect) {
|
|
120
|
+
connect = this.onConnect.bind(this)
|
|
121
|
+
provider.on('connect', connect)
|
|
122
|
+
}
|
|
123
|
+
if (!sessionDelete) {
|
|
124
|
+
sessionDelete = this.onSessionDelete.bind(this)
|
|
125
|
+
provider.on('session_delete', sessionDelete)
|
|
126
|
+
}
|
|
110
127
|
},
|
|
111
128
|
async connect({ chainId, ...rest } = {}) {
|
|
112
129
|
try {
|
|
113
130
|
const provider = await this.getProvider()
|
|
114
131
|
if (!provider) throw new ProviderNotFoundError()
|
|
115
|
-
|
|
132
|
+
if (!displayUri) {
|
|
133
|
+
displayUri = this.onDisplayUri
|
|
134
|
+
provider.on('display_uri', displayUri)
|
|
135
|
+
}
|
|
116
136
|
|
|
117
137
|
let targetChainId = chainId
|
|
118
138
|
if (!targetChainId) {
|
|
@@ -145,15 +165,33 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
145
165
|
}
|
|
146
166
|
|
|
147
167
|
// If session exists and chains are authorized, enable provider for required chain
|
|
148
|
-
const accounts = (await provider.enable()).map(getAddress)
|
|
168
|
+
const accounts = (await provider.enable()).map((x) => getAddress(x))
|
|
149
169
|
const currentChainId = await this.getChainId()
|
|
150
170
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
171
|
+
if (displayUri) {
|
|
172
|
+
provider.removeListener('display_uri', displayUri)
|
|
173
|
+
displayUri = undefined
|
|
174
|
+
}
|
|
175
|
+
if (connect) {
|
|
176
|
+
provider.removeListener('connect', connect)
|
|
177
|
+
connect = undefined
|
|
178
|
+
}
|
|
179
|
+
if (!accountsChanged) {
|
|
180
|
+
accountsChanged = this.onAccountsChanged.bind(this)
|
|
181
|
+
provider.on('accountsChanged', accountsChanged)
|
|
182
|
+
}
|
|
183
|
+
if (!chainChanged) {
|
|
184
|
+
chainChanged = this.onChainChanged.bind(this)
|
|
185
|
+
provider.on('chainChanged', chainChanged)
|
|
186
|
+
}
|
|
187
|
+
if (!disconnect) {
|
|
188
|
+
disconnect = this.onDisconnect.bind(this)
|
|
189
|
+
provider.on('disconnect', disconnect)
|
|
190
|
+
}
|
|
191
|
+
if (!sessionDelete) {
|
|
192
|
+
sessionDelete = this.onSessionDelete.bind(this)
|
|
193
|
+
provider.on('session_delete', sessionDelete)
|
|
194
|
+
}
|
|
157
195
|
|
|
158
196
|
return { accounts, chainId: currentChainId }
|
|
159
197
|
} catch (error) {
|
|
@@ -174,29 +212,41 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
174
212
|
} catch (error) {
|
|
175
213
|
if (!/No matching key/i.test((error as Error).message)) throw error
|
|
176
214
|
} finally {
|
|
177
|
-
|
|
178
|
-
'
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
215
|
+
if (chainChanged) {
|
|
216
|
+
provider?.removeListener('chainChanged', chainChanged)
|
|
217
|
+
chainChanged = undefined
|
|
218
|
+
}
|
|
219
|
+
if (disconnect) {
|
|
220
|
+
provider?.removeListener('disconnect', disconnect)
|
|
221
|
+
disconnect = undefined
|
|
222
|
+
}
|
|
223
|
+
if (!connect) {
|
|
224
|
+
connect = this.onConnect.bind(this)
|
|
225
|
+
provider?.on('connect', connect)
|
|
226
|
+
}
|
|
227
|
+
if (accountsChanged) {
|
|
228
|
+
provider?.removeListener('accountsChanged', accountsChanged)
|
|
229
|
+
accountsChanged = undefined
|
|
230
|
+
}
|
|
231
|
+
if (sessionDelete) {
|
|
232
|
+
provider?.removeListener('session_delete', sessionDelete)
|
|
233
|
+
sessionDelete = undefined
|
|
234
|
+
}
|
|
188
235
|
|
|
189
236
|
this.setRequestedChainsIds([])
|
|
190
237
|
}
|
|
191
238
|
},
|
|
192
239
|
async getAccounts() {
|
|
193
240
|
const provider = await this.getProvider()
|
|
194
|
-
return provider.accounts.map(getAddress)
|
|
241
|
+
return provider.accounts.map((x) => getAddress(x))
|
|
195
242
|
},
|
|
196
243
|
async getProvider({ chainId } = {}) {
|
|
197
244
|
async function initProvider() {
|
|
198
245
|
const optionalChains = config.chains.map((x) => x.id) as [number]
|
|
199
246
|
if (!optionalChains.length) return
|
|
247
|
+
const { EthereumProvider } = await import(
|
|
248
|
+
'@walletconnect/ethereum-provider'
|
|
249
|
+
)
|
|
200
250
|
return await EthereumProvider.init({
|
|
201
251
|
...parameters,
|
|
202
252
|
disableProviderPing: true,
|
|
@@ -245,62 +295,93 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
245
295
|
return false
|
|
246
296
|
}
|
|
247
297
|
},
|
|
248
|
-
async switchChain({ chainId }) {
|
|
249
|
-
const
|
|
298
|
+
async switchChain({ addEthereumChainParameter, chainId }) {
|
|
299
|
+
const provider = await this.getProvider()
|
|
300
|
+
if (!provider) throw new ProviderNotFoundError()
|
|
301
|
+
|
|
302
|
+
const chain = config.chains.find((x) => x.id === chainId)
|
|
250
303
|
if (!chain) throw new SwitchChainError(new ChainNotConfiguredError())
|
|
251
304
|
|
|
252
305
|
try {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
306
|
+
await Promise.all([
|
|
307
|
+
new Promise<void>((resolve) => {
|
|
308
|
+
const listener = ({
|
|
309
|
+
chainId: currentChainId,
|
|
310
|
+
}: { chainId?: number }) => {
|
|
311
|
+
if (currentChainId === chainId) {
|
|
312
|
+
config.emitter.off('change', listener)
|
|
313
|
+
resolve()
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
config.emitter.on('change', listener)
|
|
317
|
+
}),
|
|
318
|
+
provider.request({
|
|
319
|
+
method: 'wallet_switchEthereumChain',
|
|
320
|
+
params: [{ chainId: numberToHex(chainId) }],
|
|
321
|
+
}),
|
|
322
|
+
])
|
|
323
|
+
|
|
324
|
+
const requestedChains = await this.getRequestedChainsIds()
|
|
325
|
+
this.setRequestedChainsIds([...requestedChains, chainId])
|
|
326
|
+
|
|
327
|
+
return chain
|
|
328
|
+
} catch (err) {
|
|
329
|
+
const error = err as RpcError
|
|
330
|
+
|
|
331
|
+
if (/(user rejected)/i.test(error.message))
|
|
332
|
+
throw new UserRejectedRequestError(error)
|
|
333
|
+
|
|
334
|
+
// Indicates chain is not added to provider
|
|
335
|
+
try {
|
|
336
|
+
let blockExplorerUrls
|
|
337
|
+
if (addEthereumChainParameter?.blockExplorerUrls)
|
|
338
|
+
blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls
|
|
339
|
+
else
|
|
340
|
+
blockExplorerUrls = chain.blockExplorers?.default.url
|
|
341
|
+
? [chain.blockExplorers?.default.url]
|
|
342
|
+
: []
|
|
343
|
+
|
|
344
|
+
let rpcUrls
|
|
345
|
+
if (addEthereumChainParameter?.rpcUrls?.length)
|
|
346
|
+
rpcUrls = addEthereumChainParameter.rpcUrls
|
|
347
|
+
else rpcUrls = [...chain.rpcUrls.default.http]
|
|
348
|
+
|
|
349
|
+
const addEthereumChain = {
|
|
350
|
+
blockExplorerUrls,
|
|
351
|
+
chainId: numberToHex(chainId),
|
|
352
|
+
chainName: addEthereumChainParameter?.chainName ?? chain.name,
|
|
353
|
+
iconUrls: addEthereumChainParameter?.iconUrls,
|
|
354
|
+
nativeCurrency:
|
|
355
|
+
addEthereumChainParameter?.nativeCurrency ?? chain.nativeCurrency,
|
|
356
|
+
rpcUrls,
|
|
357
|
+
} satisfies AddEthereumChainParameter
|
|
257
358
|
|
|
258
|
-
if (
|
|
259
|
-
!isChainApproved &&
|
|
260
|
-
namespaceMethods.includes('wallet_addEthereumChain')
|
|
261
|
-
) {
|
|
262
359
|
await provider.request({
|
|
263
360
|
method: 'wallet_addEthereumChain',
|
|
264
|
-
params: [
|
|
265
|
-
{
|
|
266
|
-
chainId: numberToHex(chain.id),
|
|
267
|
-
blockExplorerUrls: [chain.blockExplorers?.default.url],
|
|
268
|
-
chainName: chain.name,
|
|
269
|
-
nativeCurrency: chain.nativeCurrency,
|
|
270
|
-
rpcUrls: [...chain.rpcUrls.default.http],
|
|
271
|
-
},
|
|
272
|
-
],
|
|
361
|
+
params: [addEthereumChain],
|
|
273
362
|
})
|
|
363
|
+
|
|
274
364
|
const requestedChains = await this.getRequestedChainsIds()
|
|
275
365
|
this.setRequestedChainsIds([...requestedChains, chainId])
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
await provider.request({
|
|
279
|
-
method: 'wallet_switchEthereumChain',
|
|
280
|
-
params: [{ chainId: numberToHex(chainId) }],
|
|
281
|
-
})
|
|
282
|
-
return chain
|
|
283
|
-
} catch (error) {
|
|
284
|
-
console.log({ error })
|
|
285
|
-
const message =
|
|
286
|
-
typeof error === 'string'
|
|
287
|
-
? error
|
|
288
|
-
: (error as ProviderRpcError)?.message
|
|
289
|
-
if (/user rejected request/i.test(message))
|
|
366
|
+
return chain
|
|
367
|
+
} catch (error) {
|
|
290
368
|
throw new UserRejectedRequestError(error as Error)
|
|
291
|
-
|
|
369
|
+
}
|
|
292
370
|
}
|
|
293
371
|
},
|
|
294
372
|
onAccountsChanged(accounts) {
|
|
295
373
|
if (accounts.length === 0) this.onDisconnect()
|
|
296
|
-
else
|
|
374
|
+
else
|
|
375
|
+
config.emitter.emit('change', {
|
|
376
|
+
accounts: accounts.map((x) => getAddress(x)),
|
|
377
|
+
})
|
|
297
378
|
},
|
|
298
379
|
onChainChanged(chain) {
|
|
299
|
-
const chainId =
|
|
380
|
+
const chainId = Number(chain)
|
|
300
381
|
config.emitter.emit('change', { chainId })
|
|
301
382
|
},
|
|
302
383
|
async onConnect(connectInfo) {
|
|
303
|
-
const chainId =
|
|
384
|
+
const chainId = Number(connectInfo.chainId)
|
|
304
385
|
const accounts = await this.getAccounts()
|
|
305
386
|
config.emitter.emit('connect', { accounts, chainId })
|
|
306
387
|
},
|
|
@@ -309,14 +390,26 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
309
390
|
config.emitter.emit('disconnect')
|
|
310
391
|
|
|
311
392
|
const provider = await this.getProvider()
|
|
312
|
-
|
|
313
|
-
'accountsChanged',
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
393
|
+
if (accountsChanged) {
|
|
394
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
395
|
+
accountsChanged = undefined
|
|
396
|
+
}
|
|
397
|
+
if (chainChanged) {
|
|
398
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
399
|
+
chainChanged = undefined
|
|
400
|
+
}
|
|
401
|
+
if (disconnect) {
|
|
402
|
+
provider.removeListener('disconnect', disconnect)
|
|
403
|
+
disconnect = undefined
|
|
404
|
+
}
|
|
405
|
+
if (sessionDelete) {
|
|
406
|
+
provider.removeListener('session_delete', sessionDelete)
|
|
407
|
+
sessionDelete = undefined
|
|
408
|
+
}
|
|
409
|
+
if (!connect) {
|
|
410
|
+
connect = this.onConnect.bind(this)
|
|
411
|
+
provider.on('connect', connect)
|
|
412
|
+
}
|
|
320
413
|
},
|
|
321
414
|
onDisplayUri(uri) {
|
|
322
415
|
config.emitter.emit('message', { type: 'display_uri', data: uri })
|
|
@@ -331,12 +424,6 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
331
424
|
)
|
|
332
425
|
return chainIds ?? []
|
|
333
426
|
},
|
|
334
|
-
getNamespaceMethods() {
|
|
335
|
-
if (!provider_) return []
|
|
336
|
-
const methods = provider_.session?.namespaces[NAMESPACE]
|
|
337
|
-
?.methods as NamespaceMethods[]
|
|
338
|
-
return methods ?? []
|
|
339
|
-
},
|
|
340
427
|
async getRequestedChainsIds() {
|
|
341
428
|
return (
|
|
342
429
|
(await config.storage?.getItem(this.requestedChainsStorageKey)) ?? []
|
|
@@ -352,21 +439,8 @@ export function walletConnect(parameters: WalletConnectParameters) {
|
|
|
352
439
|
* There may be a scenario where a dapp adds a chain to the
|
|
353
440
|
* connector later on, however, this chain will not have been approved or rejected
|
|
354
441
|
* by the wallet. In this case, the chain is considered stale.
|
|
355
|
-
*
|
|
356
|
-
* There are exceptions however:
|
|
357
|
-
* - If the wallet supports dynamic chain addition via `eth_addEthereumChain`,
|
|
358
|
-
* then the chain is not considered stale.
|
|
359
|
-
* - If the `isNewChainsStale` flag is falsy on the connector, then the chain is
|
|
360
|
-
* not considered stale.
|
|
361
|
-
*
|
|
362
|
-
* For the above cases, chain validation occurs dynamically when the user
|
|
363
|
-
* attempts to switch chain.
|
|
364
|
-
*
|
|
365
|
-
* Also check that dapp supports at least 1 chain from previously approved session.
|
|
366
442
|
*/
|
|
367
443
|
async isChainsStale() {
|
|
368
|
-
const namespaceMethods = this.getNamespaceMethods()
|
|
369
|
-
if (namespaceMethods.includes('wallet_addEthereumChain')) return false
|
|
370
444
|
if (!isNewChainsStale) return false
|
|
371
445
|
|
|
372
446
|
const connectorChains = config.chains.map((x) => x.id)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test-d.js","sourceRoot":"","sources":["../../../src/exports/index.test-d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAErC,uFAAuF;AACvF,YAAY,CAAC,CAAC,CAAC,CAAC,aAAa,EAAU,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test-d.d.ts","sourceRoot":"","sources":["../../../src/exports/index.test-d.ts"],"names":[],"mappings":""}
|