tempo.ts 0.7.6 → 0.8.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/CHANGELOG.md +32 -0
- package/dist/chains.d.ts +6 -20
- package/dist/chains.d.ts.map +1 -1
- package/dist/chains.js +14 -15
- package/dist/chains.js.map +1 -1
- package/dist/ox/KeyAuthorization.d.ts +356 -0
- package/dist/ox/KeyAuthorization.d.ts.map +1 -0
- package/dist/ox/KeyAuthorization.js +360 -0
- package/dist/ox/KeyAuthorization.js.map +1 -0
- package/dist/ox/SignatureEnvelope.d.ts +21 -6
- package/dist/ox/SignatureEnvelope.d.ts.map +1 -1
- package/dist/ox/SignatureEnvelope.js +43 -3
- package/dist/ox/SignatureEnvelope.js.map +1 -1
- package/dist/ox/Transaction.d.ts +5 -1
- package/dist/ox/Transaction.d.ts.map +1 -1
- package/dist/ox/Transaction.js +5 -0
- package/dist/ox/Transaction.js.map +1 -1
- package/dist/ox/TransactionEnvelopeAA.d.ts +9 -0
- package/dist/ox/TransactionEnvelopeAA.d.ts.map +1 -1
- package/dist/ox/TransactionEnvelopeAA.js +17 -4
- package/dist/ox/TransactionEnvelopeAA.js.map +1 -1
- package/dist/ox/TransactionRequest.d.ts +7 -1
- package/dist/ox/TransactionRequest.d.ts.map +1 -1
- package/dist/ox/TransactionRequest.js +12 -0
- package/dist/ox/TransactionRequest.js.map +1 -1
- package/dist/ox/index.d.ts +1 -0
- package/dist/ox/index.d.ts.map +1 -1
- package/dist/ox/index.js +1 -0
- package/dist/ox/index.js.map +1 -1
- package/dist/prool/Instance.js +1 -1
- package/dist/prool/Instance.js.map +1 -1
- package/{src/prool/internal → dist/prool}/chain.json +4 -2
- package/dist/viem/Abis.d.ts +319 -6
- package/dist/viem/Abis.d.ts.map +1 -1
- package/dist/viem/Abis.js +199 -7
- package/dist/viem/Abis.js.map +1 -1
- package/dist/viem/Account.d.ts +103 -14
- package/dist/viem/Account.d.ts.map +1 -1
- package/dist/viem/Account.js +177 -23
- package/dist/viem/Account.js.map +1 -1
- package/dist/viem/Actions/account.d.ts.map +1 -1
- package/dist/viem/Actions/account.js +4 -5
- package/dist/viem/Actions/account.js.map +1 -1
- package/dist/viem/Actions/amm.d.ts +72 -0
- package/dist/viem/Actions/amm.d.ts.map +1 -1
- package/dist/viem/Actions/dex.d.ts +156 -4
- package/dist/viem/Actions/dex.d.ts.map +1 -1
- package/dist/viem/Actions/fee.d.ts +4 -0
- package/dist/viem/Actions/fee.d.ts.map +1 -1
- package/dist/viem/Actions/reward.d.ts +158 -0
- package/dist/viem/Actions/reward.d.ts.map +1 -1
- package/dist/viem/Actions/reward.js +54 -0
- package/dist/viem/Actions/reward.js.map +1 -1
- package/dist/viem/Actions/token.d.ts +585 -0
- package/dist/viem/Actions/token.d.ts.map +1 -1
- package/dist/viem/Actions/token.js +2 -2
- package/dist/viem/Actions/token.js.map +1 -1
- package/dist/viem/Addresses.d.ts +1 -1
- package/dist/viem/Addresses.d.ts.map +1 -1
- package/dist/viem/Addresses.js +1 -1
- package/dist/viem/Addresses.js.map +1 -1
- package/dist/viem/Chain.d.ts +35 -0
- package/dist/viem/Chain.d.ts.map +1 -1
- package/dist/viem/Chain.js +37 -0
- package/dist/viem/Chain.js.map +1 -1
- package/dist/viem/Decorator.d.ts +74 -0
- package/dist/viem/Decorator.d.ts.map +1 -1
- package/dist/viem/Decorator.js +3 -0
- package/dist/viem/Decorator.js.map +1 -1
- package/dist/viem/Formatters.d.ts.map +1 -1
- package/dist/viem/Formatters.js +8 -7
- package/dist/viem/Formatters.js.map +1 -1
- package/dist/viem/Storage.d.ts +1 -0
- package/dist/viem/Storage.d.ts.map +1 -1
- package/dist/viem/Storage.js +21 -0
- package/dist/viem/Storage.js.map +1 -1
- package/dist/viem/TokenIds.d.ts +1 -1
- package/dist/viem/TokenIds.d.ts.map +1 -1
- package/dist/viem/TokenIds.js +1 -1
- package/dist/viem/TokenIds.js.map +1 -1
- package/dist/viem/Transaction.d.ts +9 -1
- package/dist/viem/Transaction.d.ts.map +1 -1
- package/dist/viem/Transaction.js +2 -1
- package/dist/viem/Transaction.js.map +1 -1
- package/dist/viem/WebAuthnP256.d.ts +4 -1
- package/dist/viem/WebAuthnP256.d.ts.map +1 -1
- package/dist/viem/WebAuthnP256.js +3 -1
- package/dist/viem/WebAuthnP256.js.map +1 -1
- package/dist/wagmi/Actions/reward.d.ts +44 -0
- package/dist/wagmi/Actions/reward.d.ts.map +1 -1
- package/dist/wagmi/Actions/reward.js +49 -0
- package/dist/wagmi/Actions/reward.js.map +1 -1
- package/dist/wagmi/Connector.d.ts +25 -8
- package/dist/wagmi/Connector.d.ts.map +1 -1
- package/dist/wagmi/Connector.js +120 -27
- package/dist/wagmi/Connector.js.map +1 -1
- package/dist/wagmi/Hooks/reward.d.ts +32 -0
- package/dist/wagmi/Hooks/reward.d.ts.map +1 -1
- package/dist/wagmi/Hooks/reward.js +39 -0
- package/dist/wagmi/Hooks/reward.js.map +1 -1
- package/package.json +3 -2
- package/src/chains.ts +14 -15
- package/src/ox/KeyAuthorization.test.ts +1332 -0
- package/src/ox/KeyAuthorization.ts +542 -0
- package/src/ox/SignatureEnvelope.test.ts +624 -0
- package/src/ox/SignatureEnvelope.ts +89 -9
- package/src/ox/Transaction.test.ts +214 -0
- package/src/ox/Transaction.ts +13 -1
- package/src/ox/TransactionEnvelopeAA.test.ts +164 -4
- package/src/ox/TransactionEnvelopeAA.ts +36 -3
- package/src/ox/TransactionRequest.ts +22 -1
- package/src/ox/e2e.test.ts +612 -5
- package/src/ox/index.ts +1 -0
- package/src/prool/Instance.ts +1 -1
- package/src/prool/chain.json +238 -0
- package/src/server/Handler.test.ts +20 -36
- package/src/viem/Abis.ts +200 -7
- package/src/viem/Account.test.ts +444 -0
- package/src/viem/Account.ts +355 -42
- package/src/viem/Actions/account.ts +3 -5
- package/src/viem/Actions/amm.test.ts +4 -4
- package/src/viem/Actions/reward.test.ts +84 -0
- package/src/viem/Actions/reward.ts +73 -0
- package/src/viem/Actions/token.test.ts +8 -8
- package/src/viem/Actions/token.ts +2 -2
- package/src/viem/Addresses.ts +1 -1
- package/src/viem/Chain.test.ts +168 -0
- package/src/viem/Chain.ts +37 -1
- package/src/viem/Decorator.ts +84 -0
- package/src/viem/Formatters.ts +8 -7
- package/src/viem/Storage.ts +22 -0
- package/src/viem/TokenIds.ts +1 -1
- package/src/viem/Transaction.ts +14 -2
- package/src/viem/WebAuthnP256.ts +8 -2
- package/src/viem/e2e.test.ts +299 -96
- package/src/wagmi/Actions/amm.test.ts +2 -2
- package/src/wagmi/Actions/reward.test.ts +36 -0
- package/src/wagmi/Actions/reward.ts +91 -0
- package/src/wagmi/Connector.test.ts +1 -1
- package/src/wagmi/Connector.ts +184 -54
- package/src/wagmi/Hooks/amm.test.ts +4 -4
- package/src/wagmi/Hooks/fee.test.ts +10 -4
- package/src/wagmi/Hooks/reward.test.ts +72 -0
- package/src/wagmi/Hooks/reward.ts +68 -0
- package/src/wagmi/Hooks/token.test.ts +0 -488
- package/dist/viem/internal/account.d.ts +0 -21
- package/dist/viem/internal/account.d.ts.map +0 -1
- package/dist/viem/internal/account.js +0 -61
- package/dist/viem/internal/account.js.map +0 -1
- package/src/viem/internal/account.ts +0 -89
package/src/viem/Account.ts
CHANGED
|
@@ -1,15 +1,57 @@
|
|
|
1
|
-
import { WebCryptoP256 } from 'ox'
|
|
2
1
|
import * as Address from 'ox/Address'
|
|
3
|
-
import
|
|
2
|
+
import * as Hex from 'ox/Hex'
|
|
4
3
|
import * as P256 from 'ox/P256'
|
|
5
4
|
import * as PublicKey from 'ox/PublicKey'
|
|
6
5
|
import * as Secp256k1 from 'ox/Secp256k1'
|
|
7
6
|
import * as Signature from 'ox/Signature'
|
|
8
7
|
import * as WebAuthnP256 from 'ox/WebAuthnP256'
|
|
8
|
+
import * as WebCryptoP256 from 'ox/WebCryptoP256'
|
|
9
|
+
import type { LocalAccount, RequiredBy, Account as viem_Account } from 'viem'
|
|
10
|
+
import {
|
|
11
|
+
hashAuthorization,
|
|
12
|
+
hashMessage,
|
|
13
|
+
hashTypedData,
|
|
14
|
+
keccak256,
|
|
15
|
+
parseAccount,
|
|
16
|
+
} from 'viem/utils'
|
|
17
|
+
import type { OneOf } from '../internal/types.js'
|
|
18
|
+
import * as KeyAuthorization from '../ox/KeyAuthorization.js'
|
|
9
19
|
import * as SignatureEnvelope from '../ox/SignatureEnvelope.js'
|
|
10
|
-
import * as
|
|
20
|
+
import * as Storage from './Storage.js'
|
|
21
|
+
import * as Transaction from './Transaction.js'
|
|
11
22
|
|
|
12
|
-
|
|
23
|
+
type StorageSchema = {
|
|
24
|
+
pendingKeyAuthorization?: KeyAuthorization.Signed | undefined
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type Account_base<source extends string = string> = RequiredBy<
|
|
28
|
+
LocalAccount<source>,
|
|
29
|
+
'sign' | 'signAuthorization'
|
|
30
|
+
> & {
|
|
31
|
+
/** Key type. */
|
|
32
|
+
keyType: SignatureEnvelope.Type
|
|
33
|
+
/** Account storage. */
|
|
34
|
+
storage: Storage.Storage<StorageSchema>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type RootAccount = Account_base<'root'> & {
|
|
38
|
+
/** Assign key authorization to the next transaction. */
|
|
39
|
+
assignKeyAuthorization: (
|
|
40
|
+
keyAuthorization: KeyAuthorization.Signed,
|
|
41
|
+
) => Promise<void>
|
|
42
|
+
/** Sign key authorization. */
|
|
43
|
+
signKeyAuthorization: (
|
|
44
|
+
key: Pick<AccessKeyAccount, 'accessKeyAddress' | 'keyType'>,
|
|
45
|
+
parameters?: Pick<KeyAuthorization.KeyAuthorization, 'expiry' | 'limits'>,
|
|
46
|
+
) => Promise<KeyAuthorization.Signed>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type AccessKeyAccount = Account_base<'accessKey'> & {
|
|
50
|
+
/** Access key ID. */
|
|
51
|
+
accessKeyAddress: Address.Address
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type Account = OneOf<RootAccount | AccessKeyAccount>
|
|
13
55
|
|
|
14
56
|
/**
|
|
15
57
|
* Instantiates an Account from a headless WebAuthn credential (P256 private key).
|
|
@@ -24,17 +66,19 @@ export type { Account } from './internal/account.js'
|
|
|
24
66
|
* @param privateKey P256 private key.
|
|
25
67
|
* @returns Account.
|
|
26
68
|
*/
|
|
27
|
-
export function fromHeadlessWebAuthn
|
|
69
|
+
export function fromHeadlessWebAuthn<
|
|
70
|
+
const options extends fromHeadlessWebAuthn.Options,
|
|
71
|
+
>(
|
|
28
72
|
privateKey: Hex.Hex,
|
|
29
|
-
options: fromHeadlessWebAuthn.Options,
|
|
30
|
-
):
|
|
31
|
-
const { rpId, origin } = options
|
|
73
|
+
options: options | fromHeadlessWebAuthn.Options,
|
|
74
|
+
): fromHeadlessWebAuthn.ReturnValue<options> {
|
|
75
|
+
const { access, rpId, origin, storage } = options
|
|
32
76
|
|
|
33
77
|
const publicKey = P256.getPublicKey({ privateKey })
|
|
34
|
-
const address = Address.fromPublicKey(publicKey)
|
|
35
78
|
|
|
36
|
-
return
|
|
37
|
-
|
|
79
|
+
return from({
|
|
80
|
+
access,
|
|
81
|
+
keyType: 'webAuthn',
|
|
38
82
|
publicKey,
|
|
39
83
|
async sign({ hash }) {
|
|
40
84
|
const { metadata, payload } = WebAuthnP256.getSignPayload({
|
|
@@ -55,20 +99,22 @@ export function fromHeadlessWebAuthn(
|
|
|
55
99
|
type: 'webAuthn',
|
|
56
100
|
})
|
|
57
101
|
},
|
|
58
|
-
|
|
59
|
-
})
|
|
102
|
+
storage,
|
|
103
|
+
}) as never
|
|
60
104
|
}
|
|
61
105
|
|
|
62
106
|
export declare namespace fromHeadlessWebAuthn {
|
|
63
107
|
export type Options = Omit<
|
|
64
108
|
WebAuthnP256.getSignPayload.Options,
|
|
65
109
|
'challenge' | 'rpId' | 'origin'
|
|
66
|
-
> &
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
110
|
+
> &
|
|
111
|
+
Pick<from.Parameters, 'access' | 'storage'> & {
|
|
112
|
+
rpId: string
|
|
113
|
+
origin: string
|
|
114
|
+
}
|
|
70
115
|
|
|
71
|
-
export type ReturnValue =
|
|
116
|
+
export type ReturnValue<options extends Options = Options> =
|
|
117
|
+
from.ReturnValue<options>
|
|
72
118
|
}
|
|
73
119
|
|
|
74
120
|
/**
|
|
@@ -84,12 +130,16 @@ export declare namespace fromHeadlessWebAuthn {
|
|
|
84
130
|
* @param privateKey P256 private key.
|
|
85
131
|
* @returns Account.
|
|
86
132
|
*/
|
|
87
|
-
export function fromP256
|
|
133
|
+
export function fromP256<const options extends fromP256.Options>(
|
|
134
|
+
privateKey: Hex.Hex,
|
|
135
|
+
options: options | fromP256.Options = {},
|
|
136
|
+
): fromP256.ReturnValue<options> {
|
|
137
|
+
const { access, storage } = options
|
|
88
138
|
const publicKey = P256.getPublicKey({ privateKey })
|
|
89
|
-
const address = Address.fromPublicKey(publicKey)
|
|
90
139
|
|
|
91
|
-
return
|
|
92
|
-
|
|
140
|
+
return from({
|
|
141
|
+
access,
|
|
142
|
+
keyType: 'p256',
|
|
93
143
|
publicKey,
|
|
94
144
|
async sign({ hash }) {
|
|
95
145
|
const signature = P256.sign({ payload: hash, privateKey })
|
|
@@ -99,12 +149,15 @@ export function fromP256(privateKey: Hex.Hex): fromP256.ReturnValue {
|
|
|
99
149
|
type: 'p256',
|
|
100
150
|
})
|
|
101
151
|
},
|
|
102
|
-
|
|
103
|
-
})
|
|
152
|
+
storage,
|
|
153
|
+
}) as never
|
|
104
154
|
}
|
|
105
155
|
|
|
106
156
|
export declare namespace fromP256 {
|
|
107
|
-
export type
|
|
157
|
+
export type Options = Pick<from.Parameters, 'access' | 'storage'>
|
|
158
|
+
|
|
159
|
+
export type ReturnValue<options extends Options = Options> =
|
|
160
|
+
from.ReturnValue<options>
|
|
108
161
|
}
|
|
109
162
|
|
|
110
163
|
/**
|
|
@@ -121,22 +174,31 @@ export declare namespace fromP256 {
|
|
|
121
174
|
* @returns Account.
|
|
122
175
|
*/
|
|
123
176
|
// TODO: this function will be redundant when Viem migrates to Ox.
|
|
124
|
-
export function fromSecp256k1
|
|
177
|
+
export function fromSecp256k1<const options extends fromSecp256k1.Options>(
|
|
178
|
+
privateKey: Hex.Hex,
|
|
179
|
+
options: options | fromSecp256k1.Options = {},
|
|
180
|
+
): fromSecp256k1.ReturnValue<options> {
|
|
181
|
+
const { access, storage } = options
|
|
125
182
|
const publicKey = Secp256k1.getPublicKey({ privateKey })
|
|
126
183
|
|
|
127
|
-
return
|
|
128
|
-
|
|
184
|
+
return from({
|
|
185
|
+
access,
|
|
186
|
+
keyType: 'secp256k1',
|
|
129
187
|
publicKey,
|
|
130
188
|
async sign(parameters) {
|
|
131
189
|
const { hash } = parameters
|
|
132
190
|
const signature = Secp256k1.sign({ payload: hash, privateKey })
|
|
133
191
|
return Signature.toHex(signature)
|
|
134
192
|
},
|
|
135
|
-
|
|
193
|
+
storage,
|
|
194
|
+
}) as never
|
|
136
195
|
}
|
|
137
196
|
|
|
138
197
|
export declare namespace fromSecp256k1 {
|
|
139
|
-
export type
|
|
198
|
+
export type Options = Pick<from.Parameters, 'access' | 'storage'>
|
|
199
|
+
|
|
200
|
+
export type ReturnValue<options extends Options = Options> =
|
|
201
|
+
from.ReturnValue<options>
|
|
140
202
|
}
|
|
141
203
|
|
|
142
204
|
/**
|
|
@@ -201,9 +263,10 @@ export function fromWebAuthnP256(
|
|
|
201
263
|
options: fromWebAuthnP256.Options = {},
|
|
202
264
|
): fromWebAuthnP256.ReturnValue {
|
|
203
265
|
const { id } = credential
|
|
266
|
+
const { storage } = options
|
|
204
267
|
const publicKey = PublicKey.fromHex(credential.publicKey)
|
|
205
|
-
return
|
|
206
|
-
|
|
268
|
+
return from({
|
|
269
|
+
keyType: 'webAuthn',
|
|
207
270
|
publicKey,
|
|
208
271
|
async sign({ hash }) {
|
|
209
272
|
const { metadata, signature } = await WebAuthnP256.sign({
|
|
@@ -218,7 +281,7 @@ export function fromWebAuthnP256(
|
|
|
218
281
|
type: 'webAuthn',
|
|
219
282
|
})
|
|
220
283
|
},
|
|
221
|
-
|
|
284
|
+
storage,
|
|
222
285
|
})
|
|
223
286
|
}
|
|
224
287
|
|
|
@@ -231,9 +294,10 @@ export declare namespace fromWebAuthnP256 {
|
|
|
231
294
|
export type Options = {
|
|
232
295
|
getFn?: WebAuthnP256.sign.Options['getFn'] | undefined
|
|
233
296
|
rpId?: WebAuthnP256.sign.Options['rpId'] | undefined
|
|
297
|
+
storage?: from.Parameters['storage'] | undefined
|
|
234
298
|
}
|
|
235
299
|
|
|
236
|
-
export type ReturnValue =
|
|
300
|
+
export type ReturnValue = from.ReturnValue
|
|
237
301
|
}
|
|
238
302
|
|
|
239
303
|
/**
|
|
@@ -252,14 +316,18 @@ export declare namespace fromWebAuthnP256 {
|
|
|
252
316
|
* @param keyPair WebCryptoP256 key pair.
|
|
253
317
|
* @returns Account.
|
|
254
318
|
*/
|
|
255
|
-
export function fromWebCryptoP256
|
|
319
|
+
export function fromWebCryptoP256<
|
|
320
|
+
const options extends fromWebCryptoP256.Options,
|
|
321
|
+
>(
|
|
256
322
|
keyPair: Awaited<ReturnType<typeof WebCryptoP256.createKeyPair>>,
|
|
257
|
-
|
|
323
|
+
options: options | fromWebCryptoP256.Options = {},
|
|
324
|
+
): fromWebCryptoP256.ReturnValue<options> {
|
|
325
|
+
const { access, storage } = options
|
|
258
326
|
const { publicKey, privateKey } = keyPair
|
|
259
|
-
const address = Address.fromPublicKey(publicKey)
|
|
260
327
|
|
|
261
|
-
return
|
|
262
|
-
|
|
328
|
+
return from({
|
|
329
|
+
access,
|
|
330
|
+
keyType: 'p256',
|
|
263
331
|
publicKey,
|
|
264
332
|
async sign({ hash }) {
|
|
265
333
|
const signature = await WebCryptoP256.sign({ payload: hash, privateKey })
|
|
@@ -270,10 +338,255 @@ export function fromWebCryptoP256(
|
|
|
270
338
|
type: 'p256',
|
|
271
339
|
})
|
|
272
340
|
},
|
|
273
|
-
|
|
274
|
-
})
|
|
341
|
+
storage,
|
|
342
|
+
}) as never
|
|
275
343
|
}
|
|
276
344
|
|
|
277
345
|
export declare namespace fromWebCryptoP256 {
|
|
278
|
-
export type
|
|
346
|
+
export type Options = Pick<from.Parameters, 'access' | 'storage'>
|
|
347
|
+
|
|
348
|
+
export type ReturnValue<options extends Options = Options> =
|
|
349
|
+
from.ReturnValue<options>
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export async function signKeyAuthorization(
|
|
353
|
+
account: LocalAccount,
|
|
354
|
+
parameters: signKeyAuthorization.Parameters,
|
|
355
|
+
): Promise<signKeyAuthorization.ReturnValue> {
|
|
356
|
+
const { key, expiry, limits } = parameters
|
|
357
|
+
const { accessKeyAddress, keyType: type } = key
|
|
358
|
+
|
|
359
|
+
const signature = await account.sign!({
|
|
360
|
+
hash: KeyAuthorization.getSignPayload({
|
|
361
|
+
address: accessKeyAddress,
|
|
362
|
+
expiry,
|
|
363
|
+
limits,
|
|
364
|
+
type,
|
|
365
|
+
}),
|
|
366
|
+
})
|
|
367
|
+
return KeyAuthorization.from({
|
|
368
|
+
address: accessKeyAddress,
|
|
369
|
+
expiry,
|
|
370
|
+
limits,
|
|
371
|
+
signature: SignatureEnvelope.from(signature),
|
|
372
|
+
type,
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export declare namespace signKeyAuthorization {
|
|
377
|
+
type Parameters = Pick<
|
|
378
|
+
KeyAuthorization.KeyAuthorization,
|
|
379
|
+
'expiry' | 'limits'
|
|
380
|
+
> & {
|
|
381
|
+
key: Pick<AccessKeyAccount, 'accessKeyAddress' | 'keyType'>
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
type ReturnValue = KeyAuthorization.Signed
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** @internal */
|
|
388
|
+
// biome-ignore lint/correctness/noUnusedVariables: _
|
|
389
|
+
function fromBase(parameters: fromBase.Parameters): Account_base {
|
|
390
|
+
const {
|
|
391
|
+
keyType = 'secp256k1',
|
|
392
|
+
parentAddress,
|
|
393
|
+
source = 'privateKey',
|
|
394
|
+
} = parameters
|
|
395
|
+
|
|
396
|
+
const address = parentAddress ?? Address.fromPublicKey(parameters.publicKey)
|
|
397
|
+
const publicKey = PublicKey.toHex(parameters.publicKey, {
|
|
398
|
+
includePrefix: false,
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
const storage = Storage.from<StorageSchema>(
|
|
402
|
+
parameters.storage ?? Storage.memory(),
|
|
403
|
+
{ key: `tempo.ts:${address.toLowerCase()}` },
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
async function sign({ hash }: { hash: Hex.Hex }) {
|
|
407
|
+
const signature = await parameters.sign({ hash })
|
|
408
|
+
if (parentAddress)
|
|
409
|
+
return SignatureEnvelope.serialize(
|
|
410
|
+
SignatureEnvelope.from({
|
|
411
|
+
userAddress: parentAddress,
|
|
412
|
+
inner: SignatureEnvelope.from(signature),
|
|
413
|
+
type: 'keychain',
|
|
414
|
+
}),
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
return signature
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return {
|
|
421
|
+
address: Address.checksum(address),
|
|
422
|
+
keyType,
|
|
423
|
+
sign,
|
|
424
|
+
async signAuthorization(parameters) {
|
|
425
|
+
const { chainId, nonce } = parameters
|
|
426
|
+
const address = parameters.contractAddress ?? parameters.address
|
|
427
|
+
const signature = await sign({
|
|
428
|
+
hash: hashAuthorization({ address, chainId, nonce }),
|
|
429
|
+
})
|
|
430
|
+
const envelope = SignatureEnvelope.from(signature)
|
|
431
|
+
if (envelope.type !== 'secp256k1')
|
|
432
|
+
throw new Error(
|
|
433
|
+
'Unsupported signature type. Expected `secp256k1` but got `' +
|
|
434
|
+
envelope.type +
|
|
435
|
+
'`.',
|
|
436
|
+
)
|
|
437
|
+
const { r, s, yParity } = envelope.signature
|
|
438
|
+
return {
|
|
439
|
+
address,
|
|
440
|
+
chainId,
|
|
441
|
+
nonce,
|
|
442
|
+
r: Hex.fromNumber(r, { size: 32 }),
|
|
443
|
+
s: Hex.fromNumber(s, { size: 32 }),
|
|
444
|
+
yParity,
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
async signMessage(parameters) {
|
|
448
|
+
const { message } = parameters
|
|
449
|
+
const signature = await sign({ hash: hashMessage(message) })
|
|
450
|
+
const envelope = SignatureEnvelope.from(signature)
|
|
451
|
+
return SignatureEnvelope.serialize(envelope)
|
|
452
|
+
},
|
|
453
|
+
async signTransaction(transaction, options) {
|
|
454
|
+
const { serializer = Transaction.serialize } = options ?? {}
|
|
455
|
+
|
|
456
|
+
const keyAuthorization =
|
|
457
|
+
(await storage?.getItem('pendingKeyAuthorization')) ?? undefined
|
|
458
|
+
if (keyAuthorization && !(transaction as any).keyAuthorization) {
|
|
459
|
+
;(transaction as any).keyAuthorization = keyAuthorization
|
|
460
|
+
await storage.removeItem('pendingKeyAuthorization')
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const signature = await sign({
|
|
464
|
+
hash: keccak256(await serializer(transaction)),
|
|
465
|
+
})
|
|
466
|
+
const envelope = SignatureEnvelope.from(signature)
|
|
467
|
+
return await serializer(transaction, envelope as never)
|
|
468
|
+
},
|
|
469
|
+
async signTypedData(typedData) {
|
|
470
|
+
const signature = await sign({ hash: hashTypedData(typedData) })
|
|
471
|
+
const envelope = SignatureEnvelope.from(signature)
|
|
472
|
+
return SignatureEnvelope.serialize(envelope)
|
|
473
|
+
},
|
|
474
|
+
publicKey,
|
|
475
|
+
source,
|
|
476
|
+
storage,
|
|
477
|
+
type: 'local',
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
declare namespace fromBase {
|
|
482
|
+
export type Parameters = {
|
|
483
|
+
/** Parent address. */
|
|
484
|
+
parentAddress?: Address.Address | undefined
|
|
485
|
+
/** Public key. */
|
|
486
|
+
publicKey: PublicKey.PublicKey
|
|
487
|
+
/** Key type. */
|
|
488
|
+
keyType?: SignatureEnvelope.Type | undefined
|
|
489
|
+
/** Sign function. */
|
|
490
|
+
sign: NonNullable<LocalAccount['sign']>
|
|
491
|
+
/** Source. */
|
|
492
|
+
source?: string | undefined
|
|
493
|
+
/**
|
|
494
|
+
* Account storage.
|
|
495
|
+
* Used for access key management, and pending key authorizations.
|
|
496
|
+
* @default `Storage.memory()`
|
|
497
|
+
*/
|
|
498
|
+
storage?: Storage.Storage | undefined
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
export type ReturnValue = Account_base
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/** @internal */
|
|
505
|
+
// biome-ignore lint/correctness/noUnusedVariables: _
|
|
506
|
+
function fromRoot(parameters: fromRoot.Parameters): RootAccount {
|
|
507
|
+
const account = fromBase(parameters)
|
|
508
|
+
return {
|
|
509
|
+
...account,
|
|
510
|
+
source: 'root',
|
|
511
|
+
async assignKeyAuthorization(keyAuthorization) {
|
|
512
|
+
account.storage.setItem('pendingKeyAuthorization', keyAuthorization)
|
|
513
|
+
},
|
|
514
|
+
async signKeyAuthorization(key, parameters = {}) {
|
|
515
|
+
const { expiry, limits } = parameters
|
|
516
|
+
const { accessKeyAddress, keyType: type } = key
|
|
517
|
+
|
|
518
|
+
const signature = await account.sign({
|
|
519
|
+
hash: KeyAuthorization.getSignPayload({
|
|
520
|
+
address: accessKeyAddress,
|
|
521
|
+
expiry,
|
|
522
|
+
limits,
|
|
523
|
+
type,
|
|
524
|
+
}),
|
|
525
|
+
})
|
|
526
|
+
const keyAuthorization = KeyAuthorization.from({
|
|
527
|
+
address: accessKeyAddress,
|
|
528
|
+
expiry,
|
|
529
|
+
limits,
|
|
530
|
+
signature: SignatureEnvelope.from(signature),
|
|
531
|
+
type,
|
|
532
|
+
})
|
|
533
|
+
return keyAuthorization
|
|
534
|
+
},
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
declare namespace fromRoot {
|
|
539
|
+
export type Parameters = fromBase.Parameters
|
|
540
|
+
|
|
541
|
+
export type ReturnValue = RootAccount
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// biome-ignore lint/correctness/noUnusedVariables: _
|
|
545
|
+
function fromAccessKey(parameters: fromAccessKey.Parameters): AccessKeyAccount {
|
|
546
|
+
const { access } = parameters
|
|
547
|
+
const { address: parentAddress } = parseAccount(access)
|
|
548
|
+
const account = fromBase({ ...parameters, parentAddress })
|
|
549
|
+
return {
|
|
550
|
+
...account,
|
|
551
|
+
accessKeyAddress: Address.fromPublicKey(parameters.publicKey),
|
|
552
|
+
source: 'accessKey',
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
declare namespace fromAccessKey {
|
|
557
|
+
export type Parameters = fromBase.Parameters & {
|
|
558
|
+
/**
|
|
559
|
+
* Parent account to access.
|
|
560
|
+
* If defined, this account will act as an "access key", and use
|
|
561
|
+
* the parent account's address as the keychain address.
|
|
562
|
+
*/
|
|
563
|
+
access: viem_Account | Address.Address
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
export type ReturnValue = AccessKeyAccount
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// biome-ignore lint/correctness/noUnusedVariables: _
|
|
570
|
+
function from<const parameters extends from.Parameters>(
|
|
571
|
+
parameters: parameters | from.Parameters,
|
|
572
|
+
): from.ReturnValue<parameters> {
|
|
573
|
+
const { access } = parameters
|
|
574
|
+
if (access) return fromAccessKey(parameters) as never
|
|
575
|
+
return fromRoot(parameters) as never
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
declare namespace from {
|
|
579
|
+
export type Parameters = OneOf<fromRoot.Parameters | fromAccessKey.Parameters>
|
|
580
|
+
|
|
581
|
+
export type ReturnValue<
|
|
582
|
+
parameters extends {
|
|
583
|
+
access?: fromAccessKey.Parameters['access'] | undefined
|
|
584
|
+
} = {
|
|
585
|
+
access?: fromAccessKey.Parameters['access'] | undefined
|
|
586
|
+
},
|
|
587
|
+
> = parameters extends {
|
|
588
|
+
access: fromAccessKey.Parameters['access']
|
|
589
|
+
}
|
|
590
|
+
? AccessKeyAccount
|
|
591
|
+
: RootAccount
|
|
279
592
|
}
|
|
@@ -63,9 +63,8 @@ export async function verifyHash<chain extends Chain | undefined>(
|
|
|
63
63
|
|
|
64
64
|
const [envelope, userAddress] = (() => {
|
|
65
65
|
const envelope = SignatureEnvelope.from(signature)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// return [envelope.inner, envelope.userAddress]
|
|
66
|
+
if (envelope.type === 'keychain')
|
|
67
|
+
return [envelope.inner, envelope.userAddress]
|
|
69
68
|
return [envelope, undefined]
|
|
70
69
|
})()
|
|
71
70
|
|
|
@@ -83,8 +82,7 @@ export async function verifyHash<chain extends Chain | undefined>(
|
|
|
83
82
|
publicKey: envelope.publicKey,
|
|
84
83
|
signature: envelope.signature,
|
|
85
84
|
})
|
|
86
|
-
|
|
87
|
-
// if (envelope.type === 'keychain') throw new Error('not supported')
|
|
85
|
+
if (envelope.type === 'keychain') throw new Error('not supported')
|
|
88
86
|
|
|
89
87
|
const address =
|
|
90
88
|
parameters.address ??
|
|
@@ -107,7 +107,7 @@ describe('mint', () => {
|
|
|
107
107
|
})
|
|
108
108
|
})
|
|
109
109
|
|
|
110
|
-
describe('burn', () => {
|
|
110
|
+
describe.skip('burn', () => {
|
|
111
111
|
test('default', async () => {
|
|
112
112
|
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
113
113
|
|
|
@@ -182,7 +182,7 @@ describe('burn', () => {
|
|
|
182
182
|
})
|
|
183
183
|
})
|
|
184
184
|
|
|
185
|
-
describe('rebalanceSwap', () => {
|
|
185
|
+
describe.skip('rebalanceSwap', () => {
|
|
186
186
|
test('default', async () => {
|
|
187
187
|
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
188
188
|
|
|
@@ -233,7 +233,7 @@ describe('rebalanceSwap', () => {
|
|
|
233
233
|
})
|
|
234
234
|
})
|
|
235
235
|
|
|
236
|
-
describe('watchRebalanceSwap', () => {
|
|
236
|
+
describe.skip('watchRebalanceSwap', () => {
|
|
237
237
|
test('default', async () => {
|
|
238
238
|
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
239
239
|
|
|
@@ -333,7 +333,7 @@ describe('watchMint', () => {
|
|
|
333
333
|
})
|
|
334
334
|
})
|
|
335
335
|
|
|
336
|
-
describe('watchBurn', () => {
|
|
336
|
+
describe.skip('watchBurn', () => {
|
|
337
337
|
test('default', async () => {
|
|
338
338
|
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
339
339
|
|
|
@@ -123,6 +123,90 @@ describe('getTotalPerSecond', () => {
|
|
|
123
123
|
})
|
|
124
124
|
})
|
|
125
125
|
|
|
126
|
+
describe('getUserRewardInfo', () => {
|
|
127
|
+
test('default', async () => {
|
|
128
|
+
const { token } = await setupToken(clientWithAccount)
|
|
129
|
+
|
|
130
|
+
const info = await actions.reward.getUserRewardInfo(clientWithAccount, {
|
|
131
|
+
token,
|
|
132
|
+
account: account.address,
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
expect(info.rewardRecipient).toBeDefined()
|
|
136
|
+
expect(info.rewardPerToken).toBeDefined()
|
|
137
|
+
expect(info.rewardBalance).toBeDefined()
|
|
138
|
+
expect(info.rewardRecipient).toBe(
|
|
139
|
+
'0x0000000000000000000000000000000000000000',
|
|
140
|
+
)
|
|
141
|
+
expect(info.rewardPerToken).toBe(0n)
|
|
142
|
+
expect(info.rewardBalance).toBe(0n)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('behavior: after opting in', async () => {
|
|
146
|
+
const { token } = await setupToken(clientWithAccount)
|
|
147
|
+
|
|
148
|
+
// Opt in to rewards
|
|
149
|
+
await actions.reward.setRecipientSync(clientWithAccount, {
|
|
150
|
+
recipient: account.address,
|
|
151
|
+
token,
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const info = await actions.reward.getUserRewardInfo(clientWithAccount, {
|
|
155
|
+
token,
|
|
156
|
+
account: account.address,
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
expect(info.rewardRecipient).toBe(account.address)
|
|
160
|
+
expect(info.rewardPerToken).toBe(0n)
|
|
161
|
+
expect(info.rewardBalance).toBe(0n)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
test('behavior: with active rewards after distribution', async () => {
|
|
165
|
+
const { token } = await setupToken(clientWithAccount)
|
|
166
|
+
|
|
167
|
+
// Opt in to rewards
|
|
168
|
+
await actions.reward.setRecipientSync(clientWithAccount, {
|
|
169
|
+
recipient: account.address,
|
|
170
|
+
token,
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
// Mint reward tokens
|
|
174
|
+
const rewardAmount = parseUnits('100', 6)
|
|
175
|
+
await actions.token.mintSync(clientWithAccount, {
|
|
176
|
+
amount: rewardAmount,
|
|
177
|
+
to: account.address,
|
|
178
|
+
token,
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// Start immediate reward to distribute rewards
|
|
182
|
+
await actions.reward.startSync(clientWithAccount, {
|
|
183
|
+
amount: rewardAmount,
|
|
184
|
+
token,
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
// Trigger reward accrual by transferring
|
|
188
|
+
await actions.token.transferSync(clientWithAccount, {
|
|
189
|
+
amount: 1n,
|
|
190
|
+
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
|
|
191
|
+
token,
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
// Check reward info shows accumulated rewards
|
|
195
|
+
const info = await actions.reward.getUserRewardInfo(clientWithAccount, {
|
|
196
|
+
token,
|
|
197
|
+
account: account.address,
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
expect(info.rewardRecipient).toBe(account.address)
|
|
201
|
+
expect(info.rewardPerToken).toBeGreaterThan(0n)
|
|
202
|
+
expect(info.rewardBalance).toBeGreaterThan(0n)
|
|
203
|
+
// Should have approximately the full reward amount (minus the 1 token transferred)
|
|
204
|
+
expect(info.rewardBalance).toBeGreaterThanOrEqual(
|
|
205
|
+
rewardAmount - parseUnits('1', 6),
|
|
206
|
+
)
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
126
210
|
describe('setRecipientSync', () => {
|
|
127
211
|
test('default', async () => {
|
|
128
212
|
const { token } = await setupToken(clientWithAccount)
|