tempo.ts 0.5.1 → 0.5.2

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.
Files changed (37) hide show
  1. package/dist/viem/Actions/policy.d.ts +9 -1
  2. package/dist/viem/Actions/policy.d.ts.map +1 -1
  3. package/dist/viem/Actions/policy.js.map +1 -1
  4. package/dist/viem/Transport.d.ts +8 -0
  5. package/dist/viem/Transport.d.ts.map +1 -1
  6. package/dist/viem/Transport.js +87 -1
  7. package/dist/viem/Transport.js.map +1 -1
  8. package/dist/wagmi/Actions/index.d.ts +1 -0
  9. package/dist/wagmi/Actions/index.d.ts.map +1 -1
  10. package/dist/wagmi/Actions/index.js +1 -0
  11. package/dist/wagmi/Actions/index.js.map +1 -1
  12. package/dist/wagmi/Actions/policy.d.ts +481 -0
  13. package/dist/wagmi/Actions/policy.d.ts.map +1 -0
  14. package/dist/wagmi/Actions/policy.js +530 -0
  15. package/dist/wagmi/Actions/policy.js.map +1 -0
  16. package/dist/wagmi/Connector.d.ts +1 -1
  17. package/dist/wagmi/Connector.d.ts.map +1 -1
  18. package/dist/wagmi/Connector.js +3 -85
  19. package/dist/wagmi/Connector.js.map +1 -1
  20. package/dist/wagmi/Hooks/index.d.ts +1 -0
  21. package/dist/wagmi/Hooks/index.d.ts.map +1 -1
  22. package/dist/wagmi/Hooks/index.js +1 -0
  23. package/dist/wagmi/Hooks/index.js.map +1 -1
  24. package/dist/wagmi/Hooks/policy.d.ts +424 -0
  25. package/dist/wagmi/Hooks/policy.d.ts.map +1 -0
  26. package/dist/wagmi/Hooks/policy.js +510 -0
  27. package/dist/wagmi/Hooks/policy.js.map +1 -0
  28. package/package.json +2 -2
  29. package/src/viem/Actions/policy.ts +25 -0
  30. package/src/viem/Transport.ts +107 -1
  31. package/src/wagmi/Actions/index.ts +1 -0
  32. package/src/wagmi/Actions/policy.test.ts +461 -0
  33. package/src/wagmi/Actions/policy.ts +819 -0
  34. package/src/wagmi/Connector.ts +4 -112
  35. package/src/wagmi/Hooks/index.ts +1 -0
  36. package/src/wagmi/Hooks/policy.test.ts +665 -0
  37. package/src/wagmi/Hooks/policy.ts +875 -0
@@ -1,4 +1,15 @@
1
- import { createTransport, type Transport } from 'viem'
1
+ import * as Address from 'ox/Address'
2
+ import * as Hash from 'ox/Hash'
3
+ import * as Hex from 'ox/Hex'
4
+ import * as Provider from 'ox/Provider'
5
+ import * as RpcRequest from 'ox/RpcRequest'
6
+ import { createClient, createTransport, type Transport } from 'viem'
7
+ import {
8
+ getTransactionReceipt,
9
+ sendTransaction,
10
+ sendTransactionSync,
11
+ } from 'viem/actions'
12
+ import type * as tempo_Chain from './Chain.js'
2
13
  import * as Transaction from './Transaction.js'
3
14
 
4
15
  export type FeePayer = Transport<typeof withFeePayer.type>
@@ -45,3 +56,98 @@ export declare namespace withFeePayer {
45
56
 
46
57
  export type ReturnValue = FeePayer
47
58
  }
59
+
60
+ /**
61
+ * Creates a transport that instruments a compatibility layer for
62
+ * `wallet_` RPC actions (`sendCalls`, `getCallsStatus`, etc).
63
+ *
64
+ * @param transport - Transport to wrap.
65
+ * @returns Transport.
66
+ */
67
+ export function walletNamespaceCompat(transport: Transport): Transport {
68
+ const sendCallsMagic = Hash.keccak256(Hex.fromString('TEMPO_5792'))
69
+
70
+ return (options) => {
71
+ const t = transport(options)
72
+
73
+ const account = options.account
74
+
75
+ type Chain = ReturnType<ReturnType<typeof tempo_Chain.define>>
76
+ const chain = options.chain as Chain
77
+
78
+ return {
79
+ ...t,
80
+ async request(args: never) {
81
+ const request = RpcRequest.from(args)
82
+
83
+ const client = createClient({
84
+ account,
85
+ chain,
86
+ transport,
87
+ })
88
+
89
+ if (request.method === 'wallet_sendCalls') {
90
+ const params = request.params[0] ?? {}
91
+ const { capabilities, chainId, from } = params
92
+ const { sync } = capabilities ?? {}
93
+
94
+ if (!account) throw new Provider.DisconnectedError()
95
+ if (!chainId) throw new Provider.UnsupportedChainIdError()
96
+ if (Number(chainId) !== client.chain.id)
97
+ throw new Provider.UnsupportedChainIdError()
98
+ if (from && !Address.isEqual(from, account.address))
99
+ throw new Provider.DisconnectedError()
100
+
101
+ const calls = (params.calls ?? []).map((call) => ({
102
+ to: call.to,
103
+ value: call.value ? BigInt(call.value) : undefined,
104
+ data: call.data,
105
+ }))
106
+
107
+ const hash = await (async () => {
108
+ if (!sync)
109
+ return sendTransaction(client, {
110
+ account,
111
+ calls,
112
+ })
113
+
114
+ const { transactionHash } = await sendTransactionSync(client, {
115
+ account,
116
+ calls,
117
+ })
118
+ return transactionHash
119
+ })()
120
+
121
+ const id = Hex.concat(hash, Hex.padLeft(chainId, 32), sendCallsMagic)
122
+
123
+ return {
124
+ capabilities: { sync },
125
+ id,
126
+ }
127
+ }
128
+
129
+ if (request.method === 'wallet_getCallsStatus') {
130
+ const [id] = request.params ?? []
131
+ if (!id) throw new Error('`id` not found')
132
+ if (!id.endsWith(sendCallsMagic.slice(2)))
133
+ throw new Error('`id` not supported')
134
+ Hex.assert(id)
135
+
136
+ const hash = Hex.slice(id, 0, 32)
137
+ const chainId = Hex.slice(id, 32, 64)
138
+
139
+ const receipt = await getTransactionReceipt(client, { hash })
140
+ return {
141
+ atomic: true,
142
+ chainId: Number(chainId),
143
+ receipts: [receipt],
144
+ status: receipt.status === 'success' ? 200 : 500,
145
+ version: '2.0.0',
146
+ }
147
+ }
148
+
149
+ return t.request(args)
150
+ },
151
+ } as never
152
+ }
153
+ }
@@ -2,5 +2,6 @@ export * as amm from './amm.js'
2
2
  export * as dex from './dex.js'
3
3
  export * as faucet from './faucet.js'
4
4
  export * as fee from './fee.js'
5
+ export * as policy from './policy.js'
5
6
  export * as reward from './reward.js'
6
7
  export * as token from './token.js'
@@ -0,0 +1,461 @@
1
+ import { connect } from '@wagmi/core'
2
+ import { describe, expect, test } from 'vitest'
3
+ import { accounts } from '../../../test/viem/config.js'
4
+ import { config, queryClient } from '../../../test/wagmi/config.js'
5
+ import * as policy from './policy.js'
6
+
7
+ const account = accounts[0]
8
+ const account2 = accounts[1]
9
+
10
+ describe('create', () => {
11
+ test('default', async () => {
12
+ await connect(config, {
13
+ connector: config.connectors[0]!,
14
+ })
15
+
16
+ const result = await policy.createSync(config, {
17
+ type: 'whitelist',
18
+ })
19
+
20
+ expect(result.receipt).toBeDefined()
21
+ expect(result.policyId).toBeDefined()
22
+ expect(result.policyType).toBe(0)
23
+ expect(result.updater).toBe(account.address)
24
+
25
+ // verify policy was created
26
+ const data = await policy.getData(config, {
27
+ policyId: result.policyId,
28
+ })
29
+ expect(data.admin).toBe(account.address)
30
+ expect(data.type).toBe('whitelist')
31
+ })
32
+
33
+ test('behavior: blacklist', async () => {
34
+ await connect(config, {
35
+ connector: config.connectors[0]!,
36
+ })
37
+
38
+ const result = await policy.createSync(config, {
39
+ type: 'blacklist',
40
+ })
41
+
42
+ expect(result.receipt).toBeDefined()
43
+ expect(result.policyId).toBeDefined()
44
+ expect(result.policyType).toBe(1)
45
+ expect(result.updater).toBe(account.address)
46
+
47
+ // verify policy was created
48
+ const data = await policy.getData(config, {
49
+ policyId: result.policyId,
50
+ })
51
+ expect(data.admin).toBe(account.address)
52
+ expect(data.type).toBe('blacklist')
53
+ })
54
+ })
55
+
56
+ describe('setAdmin', () => {
57
+ test('default', async () => {
58
+ await connect(config, {
59
+ connector: config.connectors[0]!,
60
+ })
61
+
62
+ // create policy
63
+ const { policyId } = await policy.createSync(config, {
64
+ type: 'whitelist',
65
+ })
66
+
67
+ // set new admin
68
+ const { receipt: setAdminReceipt, ...setAdminResult } =
69
+ await policy.setAdminSync(config, {
70
+ policyId,
71
+ admin: account2.address,
72
+ })
73
+ expect(setAdminReceipt).toBeDefined()
74
+ expect(setAdminResult.policyId).toBe(policyId)
75
+ expect(setAdminResult.admin).toBe(account2.address)
76
+ expect(setAdminResult.updater).toBe(account.address)
77
+
78
+ {
79
+ // verify new admin
80
+ const data = await policy.getData(config, {
81
+ policyId,
82
+ })
83
+ expect(data.admin).toBe(account2.address)
84
+ }
85
+ })
86
+ })
87
+
88
+ describe('modifyWhitelist', () => {
89
+ test('default', async () => {
90
+ await connect(config, {
91
+ connector: config.connectors[0]!,
92
+ })
93
+
94
+ // create whitelist policy
95
+ const { policyId } = await policy.createSync(config, {
96
+ type: 'whitelist',
97
+ })
98
+
99
+ // verify account2 is not authorized
100
+ {
101
+ const isAuthorized = await policy.isAuthorized(config, {
102
+ policyId,
103
+ user: account2.address,
104
+ })
105
+ expect(isAuthorized).toBe(false)
106
+ }
107
+
108
+ // add account2 to whitelist
109
+ const addResult = await policy.modifyWhitelistSync(config, {
110
+ policyId,
111
+ address: account2.address,
112
+ allowed: true,
113
+ })
114
+
115
+ expect(addResult.receipt).toBeDefined()
116
+ expect(addResult.policyId).toBe(policyId)
117
+ expect(addResult.account).toBe(account2.address)
118
+ expect(addResult.allowed).toBe(true)
119
+ expect(addResult.updater).toBe(account.address)
120
+
121
+ // verify account2 is authorized
122
+ {
123
+ const isAuthorized = await policy.isAuthorized(config, {
124
+ policyId,
125
+ user: account2.address,
126
+ })
127
+ expect(isAuthorized).toBe(true)
128
+ }
129
+
130
+ // remove account2 from whitelist
131
+ const removeResult = await policy.modifyWhitelistSync(config, {
132
+ policyId,
133
+ address: account2.address,
134
+ allowed: false,
135
+ })
136
+
137
+ expect(removeResult.receipt).toBeDefined()
138
+ expect(removeResult.policyId).toBe(policyId)
139
+ expect(removeResult.account).toBe(account2.address)
140
+ expect(removeResult.allowed).toBe(false)
141
+ expect(removeResult.updater).toBe(account.address)
142
+
143
+ // verify account2 is no longer authorized
144
+ {
145
+ const isAuthorized = await policy.isAuthorized(config, {
146
+ policyId,
147
+ user: account2.address,
148
+ })
149
+ expect(isAuthorized).toBe(false)
150
+ }
151
+ })
152
+ })
153
+
154
+ describe('modifyBlacklist', () => {
155
+ test('default', async () => {
156
+ await connect(config, {
157
+ connector: config.connectors[0]!,
158
+ })
159
+
160
+ // create blacklist policy
161
+ const { policyId } = await policy.createSync(config, {
162
+ type: 'blacklist',
163
+ })
164
+
165
+ // verify account2 is authorized (not blacklisted)
166
+ {
167
+ const isAuthorized = await policy.isAuthorized(config, {
168
+ policyId,
169
+ user: account2.address,
170
+ })
171
+ expect(isAuthorized).toBe(true)
172
+ }
173
+
174
+ // add account2 to blacklist
175
+ const addResult = await policy.modifyBlacklistSync(config, {
176
+ policyId,
177
+ address: account2.address,
178
+ restricted: true,
179
+ })
180
+
181
+ expect(addResult.receipt).toBeDefined()
182
+ expect(addResult.policyId).toBe(policyId)
183
+ expect(addResult.account).toBe(account2.address)
184
+ expect(addResult.restricted).toBe(true)
185
+ expect(addResult.updater).toBe(account.address)
186
+
187
+ // verify account2 is not authorized (blacklisted)
188
+ {
189
+ const isAuthorized = await policy.isAuthorized(config, {
190
+ policyId,
191
+ user: account2.address,
192
+ })
193
+ expect(isAuthorized).toBe(false)
194
+ }
195
+
196
+ // remove account2 from blacklist
197
+ const removeResult = await policy.modifyBlacklistSync(config, {
198
+ policyId,
199
+ address: account2.address,
200
+ restricted: false,
201
+ })
202
+
203
+ expect(removeResult.receipt).toBeDefined()
204
+ expect(removeResult.policyId).toBe(policyId)
205
+ expect(removeResult.account).toBe(account2.address)
206
+ expect(removeResult.restricted).toBe(false)
207
+ expect(removeResult.updater).toBe(account.address)
208
+
209
+ // verify account2 is authorized again
210
+ {
211
+ const isAuthorized = await policy.isAuthorized(config, {
212
+ policyId,
213
+ user: account2.address,
214
+ })
215
+ expect(isAuthorized).toBe(true)
216
+ }
217
+ })
218
+ })
219
+
220
+ describe('getData', () => {
221
+ test('default', async () => {
222
+ await connect(config, {
223
+ connector: config.connectors[0]!,
224
+ })
225
+
226
+ // create policy
227
+ const { policyId } = await policy.createSync(config, {
228
+ type: 'whitelist',
229
+ })
230
+
231
+ {
232
+ // get policy data
233
+ const data = await policy.getData(config, {
234
+ policyId,
235
+ })
236
+ expect(data.admin).toBe(account.address)
237
+ expect(data.type).toBe('whitelist')
238
+ }
239
+ })
240
+
241
+ test('behavior: blacklist', async () => {
242
+ await connect(config, {
243
+ connector: config.connectors[0]!,
244
+ })
245
+
246
+ // create blacklist policy
247
+ const { policyId } = await policy.createSync(config, {
248
+ type: 'blacklist',
249
+ })
250
+
251
+ {
252
+ // get policy data
253
+ const data = await policy.getData(config, {
254
+ policyId,
255
+ })
256
+ expect(data.admin).toBe(account.address)
257
+ expect(data.type).toBe('blacklist')
258
+ }
259
+ })
260
+
261
+ describe('queryOptions', () => {
262
+ test('default', async () => {
263
+ await connect(config, {
264
+ connector: config.connectors[0]!,
265
+ })
266
+
267
+ // create policy
268
+ const { policyId } = await policy.createSync(config, {
269
+ type: 'whitelist',
270
+ })
271
+
272
+ const options = policy.getData.queryOptions(config, {
273
+ policyId,
274
+ })
275
+ const data = await queryClient.fetchQuery(options)
276
+
277
+ expect(data.admin).toBe(account.address)
278
+ expect(data.type).toBe('whitelist')
279
+ })
280
+ })
281
+ })
282
+
283
+ describe('isAuthorized', () => {
284
+ test('special policy: always-reject (policyId 0)', async () => {
285
+ const isAuthorized = await policy.isAuthorized(config, {
286
+ policyId: 0n,
287
+ user: account.address,
288
+ })
289
+ expect(isAuthorized).toBe(false)
290
+ })
291
+
292
+ test('special policy: always-allow (policyId 1)', async () => {
293
+ const isAuthorized = await policy.isAuthorized(config, {
294
+ policyId: 1n,
295
+ user: account.address,
296
+ })
297
+ expect(isAuthorized).toBe(true)
298
+ })
299
+
300
+ describe('queryOptions', () => {
301
+ test('default', async () => {
302
+ const options = policy.isAuthorized.queryOptions(config, {
303
+ policyId: 1n,
304
+ user: account.address,
305
+ })
306
+ const isAuthorized = await queryClient.fetchQuery(options)
307
+
308
+ expect(isAuthorized).toBe(true)
309
+ })
310
+ })
311
+ })
312
+
313
+ describe('watchCreate', () => {
314
+ test('default', async () => {
315
+ await connect(config, {
316
+ connector: config.connectors[0]!,
317
+ })
318
+
319
+ const events: any[] = []
320
+ const unwatch = policy.watchCreate(config, {
321
+ onPolicyCreated: (args, log) => {
322
+ events.push({ args, log })
323
+ },
324
+ })
325
+
326
+ // create policy
327
+ await policy.createSync(config, {
328
+ type: 'whitelist',
329
+ })
330
+
331
+ await new Promise((resolve) => setTimeout(resolve, 500))
332
+ unwatch()
333
+
334
+ expect(events.length).toBe(1)
335
+ expect(events[0].args.policyId).toBeDefined()
336
+ expect(events[0].args.updater).toBe(account.address)
337
+ expect(events[0].args.type).toBe('whitelist')
338
+ })
339
+ })
340
+
341
+ describe('watchAdminUpdated', () => {
342
+ test('default', async () => {
343
+ await connect(config, {
344
+ connector: config.connectors[0]!,
345
+ })
346
+
347
+ // create policy
348
+ const { policyId } = await policy.createSync(config, {
349
+ type: 'whitelist',
350
+ })
351
+
352
+ const events: any[] = []
353
+ const unwatch = policy.watchAdminUpdated(config, {
354
+ onAdminUpdated: (args, log) => {
355
+ events.push({ args, log })
356
+ },
357
+ })
358
+
359
+ // set new admin
360
+ await policy.setAdminSync(config, {
361
+ policyId,
362
+ admin: account2.address,
363
+ })
364
+
365
+ await new Promise((resolve) => setTimeout(resolve, 500))
366
+ unwatch()
367
+
368
+ expect(events.length).toBe(1)
369
+ expect(events[0].args.policyId).toBe(policyId)
370
+ expect(events[0].args.updater).toBe(account.address)
371
+ expect(events[0].args.admin).toBe(account2.address)
372
+ })
373
+ })
374
+
375
+ describe('watchWhitelistUpdated', () => {
376
+ test('default', async () => {
377
+ await connect(config, {
378
+ connector: config.connectors[0]!,
379
+ })
380
+
381
+ // create whitelist policy
382
+ const { policyId } = await policy.createSync(config, {
383
+ type: 'whitelist',
384
+ })
385
+
386
+ const events: any[] = []
387
+ const unwatch = policy.watchWhitelistUpdated(config, {
388
+ onWhitelistUpdated: (args, log) => {
389
+ events.push({ args, log })
390
+ },
391
+ })
392
+
393
+ // add address to whitelist
394
+ await policy.modifyWhitelistSync(config, {
395
+ policyId,
396
+ address: account2.address,
397
+ allowed: true,
398
+ })
399
+
400
+ // remove address from whitelist
401
+ await policy.modifyWhitelistSync(config, {
402
+ policyId,
403
+ address: account2.address,
404
+ allowed: false,
405
+ })
406
+
407
+ await new Promise((resolve) => setTimeout(resolve, 500))
408
+ unwatch()
409
+
410
+ expect(events.length).toBe(2)
411
+ expect(events[0].args.policyId).toBe(policyId)
412
+ expect(events[0].args.updater).toBe(account.address)
413
+ expect(events[0].args.account).toBe(account2.address)
414
+ expect(events[0].args.allowed).toBe(true)
415
+ expect(events[1].args.allowed).toBe(false)
416
+ })
417
+ })
418
+
419
+ describe('watchBlacklistUpdated', () => {
420
+ test('default', async () => {
421
+ await connect(config, {
422
+ connector: config.connectors[0]!,
423
+ })
424
+
425
+ // create blacklist policy
426
+ const { policyId } = await policy.createSync(config, {
427
+ type: 'blacklist',
428
+ })
429
+
430
+ const events: any[] = []
431
+ const unwatch = policy.watchBlacklistUpdated(config, {
432
+ onBlacklistUpdated: (args, log) => {
433
+ events.push({ args, log })
434
+ },
435
+ })
436
+
437
+ // add address to blacklist
438
+ await policy.modifyBlacklistSync(config, {
439
+ policyId,
440
+ address: account2.address,
441
+ restricted: true,
442
+ })
443
+
444
+ // remove address from blacklist
445
+ await policy.modifyBlacklistSync(config, {
446
+ policyId,
447
+ address: account2.address,
448
+ restricted: false,
449
+ })
450
+
451
+ await new Promise((resolve) => setTimeout(resolve, 500))
452
+ unwatch()
453
+
454
+ expect(events.length).toBe(2)
455
+ expect(events[0].args.policyId).toBe(policyId)
456
+ expect(events[0].args.updater).toBe(account.address)
457
+ expect(events[0].args.account).toBe(account2.address)
458
+ expect(events[0].args.restricted).toBe(true)
459
+ expect(events[1].args.restricted).toBe(false)
460
+ })
461
+ })