ox 0.14.6 → 0.14.8

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 (53) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/erc8021/Attribution.js +74 -2
  3. package/_cjs/erc8021/Attribution.js.map +1 -1
  4. package/_cjs/erc8021/index.js.map +1 -1
  5. package/_cjs/tempo/AuthorizationTempo.js.map +1 -1
  6. package/_cjs/tempo/KeyAuthorization.js.map +1 -1
  7. package/_cjs/tempo/PoolId.js.map +1 -1
  8. package/_cjs/tempo/TempoAddress.js.map +1 -1
  9. package/_cjs/tempo/TokenId.js.map +1 -1
  10. package/_cjs/tempo/TxEnvelopeTempo.js.map +1 -1
  11. package/_cjs/version.js +1 -1
  12. package/_esm/erc8021/Attribution.js +118 -9
  13. package/_esm/erc8021/Attribution.js.map +1 -1
  14. package/_esm/erc8021/index.js +5 -0
  15. package/_esm/erc8021/index.js.map +1 -1
  16. package/_esm/tempo/AuthorizationTempo.js.map +1 -1
  17. package/_esm/tempo/KeyAuthorization.js.map +1 -1
  18. package/_esm/tempo/PoolId.js.map +1 -1
  19. package/_esm/tempo/TempoAddress.js.map +1 -1
  20. package/_esm/tempo/TokenId.js.map +1 -1
  21. package/_esm/tempo/TxEnvelopeTempo.js.map +1 -1
  22. package/_esm/version.js +1 -1
  23. package/_types/erc8021/Attribution.d.ts +70 -8
  24. package/_types/erc8021/Attribution.d.ts.map +1 -1
  25. package/_types/erc8021/index.d.ts +5 -0
  26. package/_types/erc8021/index.d.ts.map +1 -1
  27. package/_types/tempo/AuthorizationTempo.d.ts +4 -4
  28. package/_types/tempo/AuthorizationTempo.d.ts.map +1 -1
  29. package/_types/tempo/KeyAuthorization.d.ts +11 -9
  30. package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
  31. package/_types/tempo/PoolId.d.ts +3 -2
  32. package/_types/tempo/PoolId.d.ts.map +1 -1
  33. package/_types/tempo/TempoAddress.d.ts +4 -0
  34. package/_types/tempo/TempoAddress.d.ts.map +1 -1
  35. package/_types/tempo/TokenId.d.ts +2 -2
  36. package/_types/tempo/TokenId.d.ts.map +1 -1
  37. package/_types/tempo/TransactionRequest.d.ts +1 -1
  38. package/_types/tempo/TransactionRequest.d.ts.map +1 -1
  39. package/_types/tempo/TxEnvelopeTempo.d.ts +9 -7
  40. package/_types/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  41. package/_types/version.d.ts +1 -1
  42. package/erc8021/Attribution.ts +190 -11
  43. package/erc8021/index.ts +5 -0
  44. package/package.json +1 -1
  45. package/tempo/AuthorizationTempo.test.ts +6 -6
  46. package/tempo/AuthorizationTempo.ts +8 -5
  47. package/tempo/KeyAuthorization.ts +26 -15
  48. package/tempo/PoolId.ts +3 -2
  49. package/tempo/TempoAddress.ts +9 -0
  50. package/tempo/TokenId.ts +6 -2
  51. package/tempo/TransactionRequest.ts +1 -1
  52. package/tempo/TxEnvelopeTempo.ts +25 -13
  53. package/version.ts +1 -1
@@ -1,4 +1,5 @@
1
1
  import type * as Address from '../core/Address.js'
2
+ import * as Cbor from '../core/Cbor.js'
2
3
  import type * as Errors from '../core/Errors.js'
3
4
  import * as Hex from '../core/Hex.js'
4
5
  import type { OneOf } from '../core/internal/types.js'
@@ -9,7 +10,9 @@ import type { OneOf } from '../core/internal/types.js'
9
10
  * Represents attribution metadata that can be appended to transaction calldata
10
11
  * to track entities involved in facilitating a transaction.
11
12
  */
12
- export type Attribution = OneOf<AttributionSchemaId0 | AttributionSchemaId1>
13
+ export type Attribution = OneOf<
14
+ AttributionSchemaId0 | AttributionSchemaId1 | AttributionSchemaId2
15
+ >
13
16
 
14
17
  /**
15
18
  * Schema 0: Canonical Registry Attribution.
@@ -44,14 +47,50 @@ export type AttributionSchemaId1Registry = {
44
47
  chainId: number
45
48
  }
46
49
 
50
+ /**
51
+ * Schema 2: CBOR-Encoded Attribution.
52
+ *
53
+ * Uses CBOR encoding for extensible transaction annotation with optional fields,
54
+ * support for arbitrary metadata, and coexistence with other suffix-based systems.
55
+ */
56
+ export type AttributionSchemaId2 = {
57
+ /** Application attribution code. */
58
+ appCode?: string | undefined
59
+ /** Wallet attribution code. */
60
+ walletCode?: string | undefined
61
+ /** Custom code registries keyed by entity type. */
62
+ registries?: AttributionSchemaId2Registries | undefined
63
+ /** Arbitrary metadata key-value pairs. */
64
+ metadata?: Record<string, unknown> | undefined
65
+ /** Schema identifier (2 for CBOR-encoded). */
66
+ id?: 2 | undefined
67
+ }
68
+
69
+ export type AttributionSchemaId2Registries = {
70
+ /** Custom registry for the application entity. */
71
+ app?: AttributionSchemaId2Registry | undefined
72
+ /** Custom registry for the wallet entity. */
73
+ wallet?: AttributionSchemaId2Registry | undefined
74
+ }
75
+
76
+ export type AttributionSchemaId2Registry = {
77
+ /** Address of the custom code registry contract. */
78
+ address: Address.Address
79
+ /** Chain ID of the chain the custom code registry contract is deployed on. */
80
+ chainId: number
81
+ }
82
+
47
83
  /**
48
84
  * Attribution schema identifier.
49
85
  *
50
86
  * - `0`: Canonical registry
51
87
  * - `1`: Custom registry
88
+ * - `2`: CBOR-encoded
52
89
  */
53
90
  export type SchemaId = NonNullable<
54
- AttributionSchemaId0['id'] | AttributionSchemaId1['id']
91
+ | AttributionSchemaId0['id']
92
+ | AttributionSchemaId1['id']
93
+ | AttributionSchemaId2['id']
55
94
  >
56
95
 
57
96
  /**
@@ -84,12 +123,18 @@ export const ercSuffixSize = /*#__PURE__*/ Hex.size(ercSuffix)
84
123
  * }
85
124
  * })
86
125
  * // @log: 1
126
+ *
127
+ * const schemaId3 = Attribution.getSchemaId({
128
+ * appCode: 'baseapp',
129
+ * })
130
+ * // @log: 2
87
131
  * ```
88
132
  *
89
133
  * @param attribution - The attribution object.
90
- * @returns The schema ID (0 for canonical registry, 1 for custom registry).
134
+ * @returns The schema ID (0 for canonical registry, 1 for custom registry, 2 for CBOR-encoded).
91
135
  */
92
136
  export function getSchemaId(attribution: Attribution): SchemaId {
137
+ if ('appCode' in attribution || 'walletCode' in attribution) return 2
93
138
  if ('codeRegistry' in attribution) return 1
94
139
  return 0
95
140
  }
@@ -128,12 +173,34 @@ export declare namespace getSchemaId {
128
173
  * })
129
174
  * ```
130
175
  *
176
+ * @example
177
+ * ### Schema 2 (CBOR-Encoded)
178
+ *
179
+ * ```ts twoslash
180
+ * import { Attribution } from 'ox/erc8021'
181
+ *
182
+ * const suffix = Attribution.toDataSuffix({
183
+ * appCode: 'baseapp',
184
+ * walletCode: 'privy',
185
+ * metadata: { source: 'webapp' },
186
+ * })
187
+ * ```
188
+ *
131
189
  * @param attribution - The attribution to convert.
132
190
  * @returns The data suffix as a {@link ox#Hex.Hex} value.
133
191
  */
134
192
  export function toDataSuffix(attribution: Attribution): Hex.Hex {
193
+ // Determine schema ID
194
+ const schemaId = getSchemaId(attribution)
195
+
196
+ // Schema 2: CBOR-encoded
197
+ if (schemaId === 2) {
198
+ const schema2 = attribution as AttributionSchemaId2
199
+ return schema2ToDataSuffix(schema2)
200
+ }
201
+
135
202
  // Encode the codes as ASCII strings separated by commas
136
- const codesHex = Hex.fromString(attribution.codes.join(','))
203
+ const codesHex = Hex.fromString((attribution.codes ?? []).join(','))
137
204
 
138
205
  // Get the byte length of the encoded codes
139
206
  const codesLength = Hex.size(codesHex)
@@ -141,14 +208,11 @@ export function toDataSuffix(attribution: Attribution): Hex.Hex {
141
208
  // Encode the codes length as 1 byte
142
209
  const codesLengthHex = Hex.fromNumber(codesLength, { size: 1 })
143
210
 
144
- // Determine schema ID
145
- const schemaId = getSchemaId(attribution)
146
211
  const schemaIdHex = Hex.fromNumber(schemaId, { size: 1 })
147
212
 
148
- // Build the suffix based on schema
213
+ // Schema 1: codeRegistryAddress (20 bytes) ∥ chainId ∥ chainIdLength (1 byte) ∥ codes ∥ codesLength (1 byte) ∥ schemaId (1 byte) ∥ ercSuffix
149
214
  if (schemaId === 1) {
150
215
  const schema1 = attribution as AttributionSchemaId1
151
- // Schema 1: codeRegistryAddress (20 bytes) ∥ chainId ∥ chainIdLength (1 byte) ∥ codes ∥ codesLength (1 byte) ∥ schemaId (1 byte) ∥ ercSuffix
152
216
  return Hex.concat(
153
217
  registryToData(schema1.codeRegistry),
154
218
  codesHex,
@@ -169,6 +233,7 @@ export declare namespace toDataSuffix {
169
233
  | Hex.fromString.ErrorType
170
234
  | Hex.fromNumber.ErrorType
171
235
  | Hex.size.ErrorType
236
+ | Cbor.encode.ErrorType
172
237
  | Errors.GlobalErrorType
173
238
  }
174
239
 
@@ -198,14 +263,26 @@ export declare namespace toDataSuffix {
198
263
  * )
199
264
  * // @log: {
200
265
  * // @log: codes: ['baseapp', 'morpho'],
201
- * // @log: registry: {
202
- * // @log: address: '0xcccccccccccccccccccccccccccccccccccccccc`
266
+ * // @log: codeRegistry: {
267
+ * // @log: address: '0xcccccccccccccccccccccccccccccccccccccccc',
203
268
  * // @log: chainId: 8453,
204
- * // @log: }
269
+ * // @log: },
205
270
  * // @log: id: 1
206
271
  * // @log: }
207
272
  * ```
208
273
  *
274
+ * @example
275
+ * ### Schema 2 (CBOR-Encoded)
276
+ *
277
+ * ```ts twoslash
278
+ * import { Attribution } from 'ox/erc8021'
279
+ *
280
+ * const attribution = Attribution.fromData(
281
+ * '0xdddddddda161616762617365617070000b0280218021802180218021802180218021'
282
+ * )
283
+ * // @log: { appCode: 'baseapp', id: 2 }
284
+ * ```
285
+ *
209
286
  * @param data - The transaction calldata containing the attribution suffix.
210
287
  * @returns The extracted attribution, or undefined if no valid attribution is found.
211
288
  */
@@ -270,6 +347,10 @@ export function fromData(data: Hex.Hex): Attribution | undefined {
270
347
  id: 1,
271
348
  }
272
349
  }
350
+ // Schema 2: CBOR-encoded
351
+ if (schemaId === 2) {
352
+ return schema2FromData(data)
353
+ }
273
354
 
274
355
  // Unknown schema ID
275
356
  return undefined
@@ -325,5 +406,103 @@ export declare namespace fromData {
325
406
  | Hex.toNumber.ErrorType
326
407
  | Hex.toString.ErrorType
327
408
  | Hex.size.ErrorType
409
+ | Cbor.decode.ErrorType
328
410
  | Errors.GlobalErrorType
329
411
  }
412
+
413
+ // ---- Schema 2 helpers ----
414
+
415
+ /** Internal CBOR map shape matching the ERC-8021 spec. */
416
+ type Schema2CborMap = {
417
+ a?: string
418
+ w?: string
419
+ r?: {
420
+ a?: { c: string; a: string }
421
+ w?: { c: string; a: string }
422
+ }
423
+ m?: Record<string, unknown>
424
+ }
425
+
426
+ function schema2ToDataSuffix(attribution: AttributionSchemaId2): Hex.Hex {
427
+ // Build the CBOR map using single-letter keys per the spec
428
+ const cborMap: Schema2CborMap = {}
429
+
430
+ if (attribution.appCode) cborMap.a = attribution.appCode
431
+ if (attribution.walletCode) cborMap.w = attribution.walletCode
432
+
433
+ if (attribution.registries) {
434
+ const r: Schema2CborMap['r'] = {}
435
+ if (attribution.registries.app) {
436
+ r.a = {
437
+ c: Hex.fromNumber(attribution.registries.app.chainId),
438
+ a: attribution.registries.app.address,
439
+ }
440
+ }
441
+ if (attribution.registries.wallet) {
442
+ r.w = {
443
+ c: Hex.fromNumber(attribution.registries.wallet.chainId),
444
+ a: attribution.registries.wallet.address,
445
+ }
446
+ }
447
+ if (r.a || r.w) cborMap.r = r
448
+ }
449
+
450
+ if (attribution.metadata && Object.keys(attribution.metadata).length > 0)
451
+ cborMap.m = attribution.metadata
452
+
453
+ // Encode to CBOR
454
+ const cborHex = Cbor.encode(cborMap)
455
+ const cborBytes = Hex.size(cborHex)
456
+
457
+ // cborData ∥ cborLength (2 bytes) ∥ schemaId (1 byte) ∥ ercSuffix
458
+ return Hex.concat(
459
+ cborHex,
460
+ Hex.fromNumber(cborBytes, { size: 2 }),
461
+ Hex.fromNumber(2, { size: 1 }),
462
+ ercSuffix,
463
+ )
464
+ }
465
+
466
+ function schema2FromData(data: Hex.Hex): AttributionSchemaId2 | undefined {
467
+ // cborLength is 2 bytes before schema ID
468
+ const cborLengthHex = Hex.slice(
469
+ data,
470
+ -ercSuffixSize - 1 - 2,
471
+ -ercSuffixSize - 1,
472
+ )
473
+ const cborLength = Hex.toNumber(cborLengthHex)
474
+
475
+ // Extract CBOR data
476
+ const cborStart = -ercSuffixSize - 1 - 2 - cborLength
477
+ const cborEnd = -ercSuffixSize - 1 - 2
478
+ const cborHex = Hex.slice(data, cborStart, cborEnd)
479
+
480
+ // Decode CBOR
481
+ const decoded = Cbor.decode<Schema2CborMap>(cborHex)
482
+
483
+ const result: AttributionSchemaId2 = { id: 2 }
484
+
485
+ if (typeof decoded.a === 'string') result.appCode = decoded.a
486
+ if (typeof decoded.w === 'string') result.walletCode = decoded.w
487
+
488
+ if (decoded.r) {
489
+ const registries: AttributionSchemaId2Registries = {}
490
+ if (decoded.r.a?.c && decoded.r.a?.a) {
491
+ registries.app = {
492
+ address: decoded.r.a.a as Address.Address,
493
+ chainId: Hex.toNumber(decoded.r.a.c as Hex.Hex),
494
+ }
495
+ }
496
+ if (decoded.r.w?.c && decoded.r.w?.a) {
497
+ registries.wallet = {
498
+ address: decoded.r.w.a as Address.Address,
499
+ chainId: Hex.toNumber(decoded.r.w.c as Hex.Hex),
500
+ }
501
+ }
502
+ if (registries.app || registries.wallet) result.registries = registries
503
+ }
504
+
505
+ if (decoded.m && typeof decoded.m === 'object') result.metadata = decoded.m
506
+
507
+ return result
508
+ }
package/erc8021/index.ts CHANGED
@@ -19,6 +19,11 @@ export type {}
19
19
  * codes: ['baseapp', 'morpho'],
20
20
  * codeRegistry: { address: '0x0000000000000000000000000000000000000000', chainId: 1 },
21
21
  * })
22
+ *
23
+ * const dataSuffix3 = Attribution.toDataSuffix({
24
+ * appCode: 'baseapp',
25
+ * walletCode: 'privy',
26
+ * })
22
27
  * ```
23
28
  *
24
29
  * @example
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ox",
3
3
  "description": "Ethereum Standard Library",
4
- "version": "0.14.6",
4
+ "version": "0.14.8",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
7
7
  "types": "./_types/index.d.ts",
@@ -15,8 +15,8 @@ describe('from', () => {
15
15
  chainId: 1,
16
16
  nonce: 40n,
17
17
  })
18
- expectTypeOf(authorization).toEqualTypeOf<{
19
- readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
18
+ expectTypeOf(authorization).toExtend<{
19
+ address: `0x${string}`
20
20
  readonly chainId: 1
21
21
  readonly nonce: 40n
22
22
  }>()
@@ -48,8 +48,8 @@ describe('from', () => {
48
48
  type: 'secp256k1' as const,
49
49
  },
50
50
  })
51
- expectTypeOf(authorization).toEqualTypeOf<{
52
- readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
51
+ expectTypeOf(authorization).toExtend<{
52
+ address: `0x${string}`
53
53
  readonly chainId: 1
54
54
  readonly nonce: 40n
55
55
  readonly signature: {
@@ -111,7 +111,7 @@ describe('from', () => {
111
111
  signature,
112
112
  })
113
113
  expectTypeOf(authorization_signed).toExtend<{
114
- readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
114
+ readonly address: `0x${string}`
115
115
  readonly chainId: 1
116
116
  readonly nonce: 40n
117
117
  }>()
@@ -152,7 +152,7 @@ describe('from', () => {
152
152
  signature: signatureEnvelope,
153
153
  })
154
154
  expectTypeOf(authorization_signed).toExtend<{
155
- readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
155
+ readonly address: `0x${string}`
156
156
  readonly chainId: 1
157
157
  readonly nonce: 40n
158
158
  }>()
@@ -18,10 +18,11 @@ export type AuthorizationTempo<
18
18
  signed extends boolean = boolean,
19
19
  bigintType = bigint,
20
20
  numberType = number,
21
+ addressType = TempoAddress.Address,
21
22
  > = Compute<
22
23
  {
23
24
  /** Address of the contract to set as code for the Authority. */
24
- address: TempoAddress.Address
25
+ address: addressType
25
26
  /** Chain ID to authorize. */
26
27
  chainId: numberType
27
28
  /** Nonce of the Authority to authorize. */
@@ -283,10 +284,12 @@ export declare namespace from {
283
284
  > = Compute<
284
285
  authorization extends Rpc
285
286
  ? Signed
286
- : authorization &
287
- (signature extends SignatureEnvelope.from.Value
288
- ? { signature: SignatureEnvelope.from.ReturnValue<signature> }
289
- : {})
287
+ : TempoAddress.ResolveAddresses<
288
+ authorization &
289
+ (signature extends SignatureEnvelope.from.Value
290
+ ? { signature: SignatureEnvelope.from.ReturnValue<signature> }
291
+ : {})
292
+ >
290
293
  >
291
294
 
292
295
  type ErrorType = Errors.GlobalErrorType
@@ -32,15 +32,16 @@ export type KeyAuthorization<
32
32
  signed extends boolean = boolean,
33
33
  bigintType = bigint,
34
34
  numberType = number,
35
+ addressType = Address.Address,
35
36
  > = {
36
37
  /** Address derived from the public key of the key type. */
37
- address: TempoAddress.Address
38
+ address: addressType
38
39
  /** Chain ID for replay protection. */
39
40
  chainId: bigintType
40
41
  /** Unix timestamp when key expires (0 = never expires). */
41
42
  expiry?: numberType | null | undefined
42
43
  /** TIP20 spending limits for this key. */
43
- limits?: readonly TokenLimit<bigintType>[] | undefined
44
+ limits?: readonly TokenLimit<bigintType, addressType>[] | undefined
44
45
  /** Key type. (secp256k1, P256, WebAuthn). */
45
46
  type: SignatureEnvelope.Type
46
47
  } & (signed extends true
@@ -51,6 +52,14 @@ export type KeyAuthorization<
51
52
  | undefined
52
53
  })
53
54
 
55
+ /** Input type for a Key Authorization. */
56
+ export type Input = KeyAuthorization<
57
+ false,
58
+ bigint,
59
+ number,
60
+ TempoAddress.Address
61
+ >
62
+
54
63
  /** RPC representation of an {@link ox#KeyAuthorization.KeyAuthorization}. */
55
64
  export type Rpc = Omit<
56
65
  KeyAuthorization<false, Hex.Hex, Hex.Hex>,
@@ -62,11 +71,11 @@ export type Rpc = Omit<
62
71
  }
63
72
 
64
73
  /** Signed representation of a Key Authorization. */
65
- export type Signed<bigintType = bigint, numberType = number> = KeyAuthorization<
66
- true,
67
- bigintType,
68
- numberType
69
- >
74
+ export type Signed<
75
+ bigintType = bigint,
76
+ numberType = number,
77
+ addressType = Address.Address,
78
+ > = KeyAuthorization<true, bigintType, numberType, addressType>
70
79
 
71
80
  type BaseTuple = readonly [
72
81
  chainId: Hex.Hex,
@@ -106,9 +115,9 @@ export type Tuple<signed extends boolean = boolean> = signed extends true
106
115
  *
107
116
  * [Access Keys Specification](https://docs.tempo.xyz/protocol/transactions/spec-tempo-transaction#access-keys)
108
117
  */
109
- export type TokenLimit<bigintType = bigint> = {
118
+ export type TokenLimit<bigintType = bigint, addressType = Address.Address> = {
110
119
  /** Address of the TIP-20 token. */
111
- token: TempoAddress.Address
120
+ token: addressType
112
121
  /** Maximum spending amount for this token (enforced over the key's lifetime). */
113
122
  limit: bigintType
114
123
  }
@@ -250,7 +259,7 @@ export type TokenLimit<bigintType = bigint> = {
250
259
  * @returns The {@link ox#KeyAuthorization.KeyAuthorization}.
251
260
  */
252
261
  export function from<
253
- const authorization extends KeyAuthorization | Rpc,
262
+ const authorization extends Input | Rpc,
254
263
  const signature extends SignatureEnvelope.from.Value | undefined = undefined,
255
264
  >(
256
265
  authorization: authorization | KeyAuthorization,
@@ -291,17 +300,19 @@ export declare namespace from {
291
300
  }
292
301
 
293
302
  type ReturnType<
294
- authorization extends KeyAuthorization | Rpc = KeyAuthorization,
303
+ authorization extends KeyAuthorization | Input | Rpc = KeyAuthorization,
295
304
  signature extends SignatureEnvelope.from.Value | undefined =
296
305
  | SignatureEnvelope.from.Value
297
306
  | undefined,
298
307
  > = Compute<
299
308
  authorization extends Rpc
300
309
  ? Signed
301
- : authorization &
302
- (signature extends SignatureEnvelope.from.Value
303
- ? { signature: SignatureEnvelope.from.ReturnValue<signature> }
304
- : {})
310
+ : TempoAddress.ResolveAddresses<
311
+ authorization &
312
+ (signature extends SignatureEnvelope.from.Value
313
+ ? { signature: SignatureEnvelope.from.ReturnValue<signature> }
314
+ : {})
315
+ >
305
316
  >
306
317
 
307
318
  type ErrorType = Errors.GlobalErrorType
package/tempo/PoolId.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as Hash from '../core/Hash.js'
2
2
  import * as Hex from '../core/Hex.js'
3
+ import type * as TempoAddress from './TempoAddress.js'
3
4
  import * as TokenId from './TokenId.js'
4
5
 
5
6
  /**
@@ -35,8 +36,8 @@ export function from(value: from.Value): Hex.Hex {
35
36
  export declare namespace from {
36
37
  export type Value = {
37
38
  /** User token. */
38
- userToken: TokenId.TokenIdOrAddress
39
+ userToken: TokenId.TokenIdOrAddress<TempoAddress.Address>
39
40
  /** Validator token. */
40
- validatorToken: TokenId.TokenIdOrAddress
41
+ validatorToken: TokenId.TokenIdOrAddress<TempoAddress.Address>
41
42
  }
42
43
  }
@@ -9,6 +9,15 @@ export type Address = core_Address.Address | Tempo
9
9
  /** Root type for a Tempo Address. */
10
10
  export type Tempo = Compute<`tempox${string}`>
11
11
 
12
+ /** Deeply converts all {@link ox#TempoAddress.Tempo} types to {@link ox#Address.Address}. */
13
+ export type ResolveAddresses<type> = type extends Tempo
14
+ ? core_Address.Address
15
+ : type extends readonly (infer item)[]
16
+ ? readonly ResolveAddresses<item>[]
17
+ : type extends object
18
+ ? { [key in keyof type]: ResolveAddresses<type[key]> }
19
+ : type
20
+
12
21
  /**
13
22
  * Resolves an address input (either an Ethereum hex address or a Tempo address)
14
23
  * to an Ethereum hex address.
package/tempo/TokenId.ts CHANGED
@@ -7,7 +7,9 @@ import * as TempoAddress from './TempoAddress.js'
7
7
  const tip20Prefix = '0x20c0'
8
8
 
9
9
  export type TokenId = bigint
10
- export type TokenIdOrAddress = TokenId | TempoAddress.Address
10
+ export type TokenIdOrAddress<addressType = Address.Address> =
11
+ | TokenId
12
+ | addressType
11
13
 
12
14
  /**
13
15
  * Converts a token ID or address to a token ID.
@@ -73,7 +75,9 @@ export function fromAddress(address: TempoAddress.Address): TokenId {
73
75
  * @param tokenId - The token ID.
74
76
  * @returns The address.
75
77
  */
76
- export function toAddress(tokenId: TokenIdOrAddress): Address.Address {
78
+ export function toAddress(
79
+ tokenId: TokenIdOrAddress<TempoAddress.Address>,
80
+ ): Address.Address {
77
81
  if (typeof tokenId === 'string') {
78
82
  const resolved = TempoAddress.resolve(tokenId as TempoAddress.Address)
79
83
  Address.assert(resolved)
@@ -35,7 +35,7 @@ export type TransactionRequest<
35
35
  keyAuthorization?: KeyAuthorization.KeyAuthorization<true> | undefined
36
36
  keyData?: Hex.Hex | undefined
37
37
  keyType?: KeyType | undefined
38
- feeToken?: TokenId.TokenIdOrAddress | undefined
38
+ feeToken?: TokenId.TokenIdOrAddress<TempoAddress.Address> | undefined
39
39
  nonceKey?: 'random' | bigintType | undefined
40
40
  validBefore?: numberType | undefined
41
41
  validAfter?: numberType | undefined
@@ -69,6 +69,7 @@ export type TxEnvelopeTempo<
69
69
  bigintType = bigint,
70
70
  numberType = number,
71
71
  type extends string = Type,
72
+ addressType = Address.Address,
72
73
  > = Compute<
73
74
  {
74
75
  /** EIP-2930 Access List. */
@@ -78,11 +79,11 @@ export type TxEnvelopeTempo<
78
79
  | AuthorizationTempo.ListSigned<bigintType, numberType>
79
80
  | undefined
80
81
  /** Array of calls to execute. */
81
- calls: readonly Call<bigintType, TempoAddress.Address>[]
82
+ calls: readonly Call<bigintType, addressType>[]
82
83
  /** EIP-155 Chain ID. */
83
84
  chainId: numberType
84
85
  /** Sender of the transaction. */
85
- from?: TempoAddress.Address | undefined
86
+ from?: addressType | undefined
86
87
  /** Gas provided for transaction execution */
87
88
  gas?: bigintType | undefined
88
89
  /** Fee payer signature. */
@@ -100,7 +101,7 @@ export type TxEnvelopeTempo<
100
101
  * The authorization must be signed with the root key, the tx can be signed by the Keychain signature.
101
102
  */
102
103
  keyAuthorization?:
103
- | KeyAuthorization.Signed<bigintType, numberType>
104
+ | KeyAuthorization.Signed<bigintType, numberType, addressType>
104
105
  | undefined
105
106
  /** Total fee per gas in wei (gasPrice/baseFeePerGas + maxPriorityFeePerGas). */
106
107
  maxFeePerGas?: bigintType | undefined
@@ -127,6 +128,15 @@ export type TxEnvelopeTempo<
127
128
  })
128
129
  >
129
130
 
131
+ /** Input type that accepts TempoAddress for `calls.to`, `from`, etc. */
132
+ export type Input = TxEnvelopeTempo<
133
+ boolean,
134
+ bigint,
135
+ number,
136
+ Type,
137
+ TempoAddress.Address
138
+ >
139
+
130
140
  export type Rpc<signed extends boolean = boolean> = TxEnvelopeTempo<
131
141
  signed,
132
142
  Hex.Hex,
@@ -486,10 +496,10 @@ export declare namespace deserialize {
486
496
  * @returns A Tempo Transaction Envelope.
487
497
  */
488
498
  export function from<
489
- const envelope extends UnionPartialBy<TxEnvelopeTempo, 'type'> | Serialized,
499
+ const envelope extends UnionPartialBy<Input, 'type'> | Serialized,
490
500
  const signature extends SignatureEnvelope.from.Value | undefined = undefined,
491
501
  >(
492
- envelope: envelope | UnionPartialBy<TxEnvelopeTempo, 'type'> | Serialized,
502
+ envelope: envelope | UnionPartialBy<Input, 'type'> | Serialized,
493
503
  options: from.Options<signature> = {},
494
504
  ): from.ReturnValue<envelope, signature> {
495
505
  const { feePayerSignature, signature } = options
@@ -532,20 +542,22 @@ export declare namespace from {
532
542
  }
533
543
 
534
544
  type ReturnValue<
535
- envelope extends UnionPartialBy<TxEnvelopeTempo, 'type'> | Hex.Hex =
545
+ envelope extends UnionPartialBy<Input, 'type'> | Hex.Hex =
536
546
  | TxEnvelopeTempo
537
547
  | Hex.Hex,
538
548
  signature extends SignatureEnvelope.from.Value | undefined = undefined,
539
549
  > = Compute<
540
550
  envelope extends Hex.Hex
541
551
  ? TxEnvelopeTempo
542
- : Assign<
543
- envelope,
544
- (signature extends SignatureEnvelope.from.Value
545
- ? { signature: SignatureEnvelope.from.ReturnValue<signature> }
546
- : {}) & {
547
- readonly type: 'tempo'
548
- }
552
+ : TempoAddress.ResolveAddresses<
553
+ Assign<
554
+ envelope,
555
+ (signature extends SignatureEnvelope.from.Value
556
+ ? { signature: SignatureEnvelope.from.ReturnValue<signature> }
557
+ : {}) & {
558
+ readonly type: 'tempo'
559
+ }
560
+ >
549
561
  >
550
562
  >
551
563
 
package/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @internal */
2
- export const version = '0.14.6'
2
+ export const version = '0.14.8'