ox 0.14.12 → 0.14.14
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 +12 -0
- package/_cjs/tempo/KeyAuthorization.js +21 -12
- package/_cjs/tempo/KeyAuthorization.js.map +1 -1
- package/_cjs/tempo/RpcSchema.js +3 -0
- package/_cjs/tempo/RpcSchema.js.map +1 -0
- package/_cjs/tempo/index.js +2 -1
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/tempo/KeyAuthorization.js +23 -14
- package/_esm/tempo/KeyAuthorization.js.map +1 -1
- package/_esm/tempo/RpcSchema.js +2 -0
- package/_esm/tempo/RpcSchema.js.map +1 -0
- package/_esm/tempo/index.js +19 -0
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/core/RpcSchema.d.ts +64 -0
- package/_types/core/RpcSchema.d.ts.map +1 -1
- package/_types/tempo/KeyAuthorization.d.ts +11 -7
- package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
- package/_types/tempo/RpcSchema.d.ts +70 -0
- package/_types/tempo/RpcSchema.d.ts.map +1 -0
- package/_types/tempo/index.d.ts +19 -0
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/core/RpcSchema.ts +85 -0
- package/package.json +6 -1
- package/tempo/KeyAuthorization.test.ts +105 -10
- package/tempo/KeyAuthorization.ts +37 -23
- package/tempo/RpcSchema/package.json +6 -0
- package/tempo/RpcSchema.ts +74 -0
- package/tempo/e2e.test.ts +87 -8
- package/tempo/index.ts +20 -0
- package/version.ts +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type * as Block from '../core/Block.js';
|
|
2
|
+
import type * as BlockOverrides from '../core/BlockOverrides.js';
|
|
3
|
+
import type * as Hex from '../core/Hex.js';
|
|
4
|
+
import type * as Log from '../core/Log.js';
|
|
5
|
+
import type * as RpcSchema from '../core/RpcSchema.js';
|
|
6
|
+
import type * as StateOverrides from '../core/StateOverrides.js';
|
|
7
|
+
import type * as TransactionRequest from './TransactionRequest.js';
|
|
8
|
+
/**
|
|
9
|
+
* Union of all JSON-RPC Methods for the `tempo_` namespace.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts twoslash
|
|
13
|
+
* import { RpcSchema } from 'ox/tempo'
|
|
14
|
+
*
|
|
15
|
+
* type Schema = RpcSchema.Tempo
|
|
16
|
+
* // ^?
|
|
17
|
+
*
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
*
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
*
|
|
25
|
+
*
|
|
26
|
+
*
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export type Tempo = RpcSchema.From<{
|
|
31
|
+
Request: {
|
|
32
|
+
method: 'tempo_simulateV1';
|
|
33
|
+
params: [
|
|
34
|
+
{
|
|
35
|
+
blockStateCalls: readonly {
|
|
36
|
+
blockOverrides?: BlockOverrides.Rpc | undefined;
|
|
37
|
+
calls?: readonly TransactionRequest.Rpc[] | undefined;
|
|
38
|
+
stateOverrides?: StateOverrides.Rpc | undefined;
|
|
39
|
+
}[];
|
|
40
|
+
returnFullTransactions?: boolean | undefined;
|
|
41
|
+
traceTransfers?: boolean | undefined;
|
|
42
|
+
validation?: boolean | undefined;
|
|
43
|
+
},
|
|
44
|
+
block: Block.Number<Hex.Hex> | Block.Tag | Block.Hash | Block.Identifier
|
|
45
|
+
];
|
|
46
|
+
};
|
|
47
|
+
ReturnType: {
|
|
48
|
+
blocks: readonly (Block.Rpc & {
|
|
49
|
+
calls?: readonly {
|
|
50
|
+
error?: {
|
|
51
|
+
data?: Hex.Hex | undefined;
|
|
52
|
+
code: number;
|
|
53
|
+
message: string;
|
|
54
|
+
} | undefined;
|
|
55
|
+
logs?: readonly Log.Rpc[] | undefined;
|
|
56
|
+
gasUsed: Hex.Hex;
|
|
57
|
+
returnData: Hex.Hex;
|
|
58
|
+
status: Hex.Hex;
|
|
59
|
+
}[] | undefined;
|
|
60
|
+
})[];
|
|
61
|
+
tokenMetadata: {
|
|
62
|
+
[address: Hex.Hex]: {
|
|
63
|
+
name: string;
|
|
64
|
+
symbol: string;
|
|
65
|
+
currency: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
}>;
|
|
70
|
+
//# sourceMappingURL=RpcSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RpcSchema.d.ts","sourceRoot":"","sources":["../../tempo/RpcSchema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAChE,OAAO,KAAK,KAAK,GAAG,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,KAAK,GAAG,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAChE,OAAO,KAAK,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAElE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;IACjC,OAAO,EAAE;QACP,MAAM,EAAE,kBAAkB,CAAA;QAC1B,MAAM,EAAE;YACN;gBACE,eAAe,EAAE,SAAS;oBACxB,cAAc,CAAC,EAAE,cAAc,CAAC,GAAG,GAAG,SAAS,CAAA;oBAC/C,KAAK,CAAC,EAAE,SAAS,kBAAkB,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;oBACrD,cAAc,CAAC,EAAE,cAAc,CAAC,GAAG,GAAG,SAAS,CAAA;iBAChD,EAAE,CAAA;gBACH,sBAAsB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;gBAC5C,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;gBACpC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;aACjC;YACD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,UAAU;SACzE,CAAA;KACF,CAAA;IACD,UAAU,EAAE;QACV,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,GAAG;YAC5B,KAAK,CAAC,EACF,SAAS;gBACP,KAAK,CAAC,EACF;oBACE,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,SAAS,CAAA;oBAC1B,IAAI,EAAE,MAAM,CAAA;oBACZ,OAAO,EAAE,MAAM,CAAA;iBAChB,GACD,SAAS,CAAA;gBACb,IAAI,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;gBACrC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAA;gBAChB,UAAU,EAAE,GAAG,CAAC,GAAG,CAAA;gBACnB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAA;aAChB,EAAE,GACH,SAAS,CAAA;SACd,CAAC,EAAE,CAAA;QACJ,aAAa,EAAE;YACb,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG;gBAClB,IAAI,EAAE,MAAM,CAAA;gBACZ,MAAM,EAAE,MAAM,CAAA;gBACd,QAAQ,EAAE,MAAM,CAAA;aACjB,CAAA;SACF,CAAA;KACF,CAAA;CACF,CAAC,CAAA"}
|
package/_types/tempo/index.d.ts
CHANGED
|
@@ -123,6 +123,25 @@ export * as Period from './Period.js';
|
|
|
123
123
|
* @category Reference
|
|
124
124
|
*/
|
|
125
125
|
export * as PoolId from './PoolId.js';
|
|
126
|
+
/**
|
|
127
|
+
* Union of all JSON-RPC Methods for the `tempo_` namespace.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts twoslash
|
|
131
|
+
* import { Provider, RpcSchema } from 'ox'
|
|
132
|
+
* import { RpcSchema as TempoRpcSchema } from 'ox/tempo'
|
|
133
|
+
*
|
|
134
|
+
* const schema = RpcSchema.from<
|
|
135
|
+
* | RpcSchema.Default
|
|
136
|
+
* | TempoRpcSchema.Tempo
|
|
137
|
+
* >()
|
|
138
|
+
*
|
|
139
|
+
* const provider = Provider.from(window.ethereum!, { schema })
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @category Reference
|
|
143
|
+
*/
|
|
144
|
+
export * as RpcSchema from './RpcSchema.js';
|
|
126
145
|
/**
|
|
127
146
|
* Signature envelope utilities for secp256k1, P256, WebAuthn, and keychain signatures.
|
|
128
147
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,YAAY,EAAE,CAAA;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,YAAY,EAAE,CAAA;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA"}
|
package/_types/version.d.ts
CHANGED
package/core/RpcSchema.ts
CHANGED
|
@@ -271,3 +271,88 @@ export type Default = ResolvedRegister['RpcSchema']
|
|
|
271
271
|
export type MethodNameGeneric<schema extends Generic = Generic> =
|
|
272
272
|
| schema['Request']['method']
|
|
273
273
|
| (string & {})
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Converts an Ox {@link ox#RpcSchema.Generic} (union of `{ Request, ReturnType }`) to
|
|
277
|
+
* a [Viem-compatible RPC schema](https://viem.sh) (tuple of `{ Method, Parameters, ReturnType }`).
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts twoslash
|
|
281
|
+
* import { RpcSchema } from 'ox'
|
|
282
|
+
*
|
|
283
|
+
* type ViemSchema = RpcSchema.ToViem<
|
|
284
|
+
* | {
|
|
285
|
+
* Request: { method: 'eth_blockNumber'; params?: undefined }
|
|
286
|
+
* ReturnType: `0x${string}`
|
|
287
|
+
* }
|
|
288
|
+
* | {
|
|
289
|
+
* Request: { method: 'eth_chainId'; params?: undefined }
|
|
290
|
+
* ReturnType: `0x${string}`
|
|
291
|
+
* }
|
|
292
|
+
* >
|
|
293
|
+
* // ^? [{ Method: 'eth_blockNumber'; Parameters?: undefined; ReturnType: `0x${string}` }, ...]
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
export type ToViem<schema extends Generic> = UnionToTuple<
|
|
297
|
+
schema extends schema
|
|
298
|
+
? {
|
|
299
|
+
Method: schema['Request']['method']
|
|
300
|
+
Parameters: schema['Request']['params']
|
|
301
|
+
ReturnType: schema extends { ReturnType: infer r } ? r : unknown
|
|
302
|
+
}
|
|
303
|
+
: never
|
|
304
|
+
>
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Converts a [Viem-compatible RPC schema](https://viem.sh) (tuple of `{ Method, Parameters, ReturnType }`)
|
|
308
|
+
* to an Ox {@link ox#RpcSchema.Generic} (union of `{ Request, ReturnType }`).
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```ts twoslash
|
|
312
|
+
* import { RpcSchema } from 'ox'
|
|
313
|
+
*
|
|
314
|
+
* type OxSchema = RpcSchema.FromViem<[
|
|
315
|
+
* { Method: 'eth_blockNumber'; Parameters?: undefined; ReturnType: `0x${string}` },
|
|
316
|
+
* { Method: 'eth_chainId'; Parameters?: undefined; ReturnType: `0x${string}` },
|
|
317
|
+
* ]>
|
|
318
|
+
* // ^? { Request: { method: 'eth_blockNumber'; params?: undefined }; ReturnType: `0x${string}` } | ...
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
export type FromViem<schema extends readonly ViemSchemaItem[]> = {
|
|
322
|
+
[k in keyof schema]: schema[k] extends ViemSchemaItem
|
|
323
|
+
? {
|
|
324
|
+
Request: {
|
|
325
|
+
method: schema[k]['Method']
|
|
326
|
+
params: schema[k]['Parameters']
|
|
327
|
+
}
|
|
328
|
+
ReturnType: schema[k]['ReturnType']
|
|
329
|
+
}
|
|
330
|
+
: never
|
|
331
|
+
}[number]
|
|
332
|
+
|
|
333
|
+
/** @internal */
|
|
334
|
+
type ViemSchemaItem = {
|
|
335
|
+
Method: string
|
|
336
|
+
Parameters?: unknown
|
|
337
|
+
ReturnType?: unknown
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// --- Union-to-tuple helpers (order is not guaranteed, but stable) ---
|
|
341
|
+
/** @internal */
|
|
342
|
+
type UnionToIntersection<union> = (
|
|
343
|
+
union extends unknown
|
|
344
|
+
? (arg: () => union) => void
|
|
345
|
+
: never
|
|
346
|
+
) extends (arg: infer intersection) => void
|
|
347
|
+
? intersection
|
|
348
|
+
: never
|
|
349
|
+
|
|
350
|
+
/** @internal */
|
|
351
|
+
type UnionLast<union> = UnionToIntersection<union> extends () => infer last
|
|
352
|
+
? last
|
|
353
|
+
: never
|
|
354
|
+
|
|
355
|
+
/** @internal */
|
|
356
|
+
type UnionToTuple<union, last = UnionLast<union>> = [union] extends [never]
|
|
357
|
+
? []
|
|
358
|
+
: [...UnionToTuple<Exclude<union, last>>, last]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ox",
|
|
3
3
|
"description": "Ethereum Standard Library",
|
|
4
|
-
"version": "0.14.
|
|
4
|
+
"version": "0.14.14",
|
|
5
5
|
"main": "./_cjs/index.js",
|
|
6
6
|
"module": "./_esm/index.js",
|
|
7
7
|
"types": "./_types/index.d.ts",
|
|
@@ -519,6 +519,11 @@
|
|
|
519
519
|
"import": "./_esm/tempo/PoolId.js",
|
|
520
520
|
"default": "./_cjs/tempo/PoolId.js"
|
|
521
521
|
},
|
|
522
|
+
"./tempo/RpcSchema": {
|
|
523
|
+
"types": "./_types/tempo/RpcSchema.d.ts",
|
|
524
|
+
"import": "./_esm/tempo/RpcSchema.js",
|
|
525
|
+
"default": "./_cjs/tempo/RpcSchema.js"
|
|
526
|
+
},
|
|
522
527
|
"./tempo/SignatureEnvelope": {
|
|
523
528
|
"types": "./_types/tempo/SignatureEnvelope.d.ts",
|
|
524
529
|
"import": "./_esm/tempo/SignatureEnvelope.js",
|
|
@@ -1824,7 +1824,7 @@ describe('toTuple', () => {
|
|
|
1824
1824
|
type: 'secp256k1',
|
|
1825
1825
|
scopes: [
|
|
1826
1826
|
{
|
|
1827
|
-
|
|
1827
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
1828
1828
|
},
|
|
1829
1829
|
],
|
|
1830
1830
|
})
|
|
@@ -1851,7 +1851,7 @@ describe('toTuple', () => {
|
|
|
1851
1851
|
const serialized = KeyAuthorization.serialize(authorization)
|
|
1852
1852
|
const restored = KeyAuthorization.deserialize(serialized)
|
|
1853
1853
|
expect(restored.scopes).toHaveLength(1)
|
|
1854
|
-
expect(restored.scopes?.[0]?.
|
|
1854
|
+
expect(restored.scopes?.[0]?.address).toBe(
|
|
1855
1855
|
'0x1234567890123456789012345678901234567890',
|
|
1856
1856
|
)
|
|
1857
1857
|
expect(restored.scopes?.[0]?.selector).toBeUndefined()
|
|
@@ -1864,11 +1864,11 @@ describe('toTuple', () => {
|
|
|
1864
1864
|
type: 'secp256k1',
|
|
1865
1865
|
scopes: [
|
|
1866
1866
|
{
|
|
1867
|
-
|
|
1867
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
1868
1868
|
selector: '0xa9059cbb', // transfer
|
|
1869
1869
|
},
|
|
1870
1870
|
{
|
|
1871
|
-
|
|
1871
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
1872
1872
|
selector: '0x095ea7b3', // approve
|
|
1873
1873
|
},
|
|
1874
1874
|
],
|
|
@@ -1889,7 +1889,7 @@ describe('toTuple', () => {
|
|
|
1889
1889
|
type: 'secp256k1',
|
|
1890
1890
|
scopes: [
|
|
1891
1891
|
{
|
|
1892
|
-
|
|
1892
|
+
address: token,
|
|
1893
1893
|
selector: '0xa9059cbb',
|
|
1894
1894
|
recipients: [
|
|
1895
1895
|
'0x1111111111111111111111111111111111111111',
|
|
@@ -1952,7 +1952,7 @@ describe('toTuple', () => {
|
|
|
1952
1952
|
],
|
|
1953
1953
|
scopes: [
|
|
1954
1954
|
{
|
|
1955
|
-
|
|
1955
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
1956
1956
|
selector: '0xa9059cbb',
|
|
1957
1957
|
recipients: ['0x1111111111111111111111111111111111111111'],
|
|
1958
1958
|
},
|
|
@@ -1975,7 +1975,7 @@ describe('toTuple', () => {
|
|
|
1975
1975
|
type: 'secp256k1',
|
|
1976
1976
|
scopes: [
|
|
1977
1977
|
{
|
|
1978
|
-
|
|
1978
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
1979
1979
|
selector: '0xa9059cbb',
|
|
1980
1980
|
},
|
|
1981
1981
|
],
|
|
@@ -1992,7 +1992,7 @@ describe('toTuple', () => {
|
|
|
1992
1992
|
type: 'secp256k1',
|
|
1993
1993
|
scopes: [
|
|
1994
1994
|
{
|
|
1995
|
-
|
|
1995
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
1996
1996
|
selector: '0x095ea7b3',
|
|
1997
1997
|
},
|
|
1998
1998
|
],
|
|
@@ -2000,6 +2000,101 @@ describe('toTuple', () => {
|
|
|
2000
2000
|
expect(KeyAuthorization.hash(authorization2)).not.toBe(hash1)
|
|
2001
2001
|
})
|
|
2002
2002
|
|
|
2003
|
+
test('call scopes: selector from function signature string', () => {
|
|
2004
|
+
const authorization = KeyAuthorization.from({
|
|
2005
|
+
address,
|
|
2006
|
+
chainId: 1n,
|
|
2007
|
+
type: 'secp256k1',
|
|
2008
|
+
scopes: [
|
|
2009
|
+
{
|
|
2010
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
2011
|
+
selector: 'function transfer(address,uint256)',
|
|
2012
|
+
},
|
|
2013
|
+
{
|
|
2014
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
2015
|
+
selector: 'function approve(address,uint256)',
|
|
2016
|
+
},
|
|
2017
|
+
],
|
|
2018
|
+
})
|
|
2019
|
+
|
|
2020
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
2021
|
+
const restored = KeyAuthorization.deserialize(serialized)
|
|
2022
|
+
expect(restored.scopes).toHaveLength(2)
|
|
2023
|
+
// transfer(address,uint256) => 0xa9059cbb
|
|
2024
|
+
expect(restored.scopes?.[0]?.selector).toBe('0xa9059cbb')
|
|
2025
|
+
// approve(address,uint256) => 0x095ea7b3
|
|
2026
|
+
expect(restored.scopes?.[1]?.selector).toBe('0x095ea7b3')
|
|
2027
|
+
})
|
|
2028
|
+
|
|
2029
|
+
test('call scopes: selector from signature with recipients', () => {
|
|
2030
|
+
const authorization = KeyAuthorization.from({
|
|
2031
|
+
address,
|
|
2032
|
+
chainId: 1n,
|
|
2033
|
+
type: 'secp256k1',
|
|
2034
|
+
scopes: [
|
|
2035
|
+
{
|
|
2036
|
+
address: token,
|
|
2037
|
+
selector: 'function transfer(address,uint256)',
|
|
2038
|
+
recipients: ['0x1111111111111111111111111111111111111111'],
|
|
2039
|
+
},
|
|
2040
|
+
],
|
|
2041
|
+
})
|
|
2042
|
+
|
|
2043
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
2044
|
+
const restored = KeyAuthorization.deserialize(serialized)
|
|
2045
|
+
expect(restored.scopes?.[0]?.selector).toBe('0xa9059cbb')
|
|
2046
|
+
expect(restored.scopes?.[0]?.recipients).toEqual([
|
|
2047
|
+
'0x1111111111111111111111111111111111111111',
|
|
2048
|
+
])
|
|
2049
|
+
})
|
|
2050
|
+
|
|
2051
|
+
test('call scopes: selector from bare signature (no function prefix)', () => {
|
|
2052
|
+
const authorization = KeyAuthorization.from({
|
|
2053
|
+
address,
|
|
2054
|
+
chainId: 1n,
|
|
2055
|
+
type: 'secp256k1',
|
|
2056
|
+
scopes: [
|
|
2057
|
+
{
|
|
2058
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
2059
|
+
selector: 'transfer(address,uint256)',
|
|
2060
|
+
},
|
|
2061
|
+
{
|
|
2062
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
2063
|
+
selector: 'approve(address,uint256)',
|
|
2064
|
+
},
|
|
2065
|
+
],
|
|
2066
|
+
})
|
|
2067
|
+
|
|
2068
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
2069
|
+
const restored = KeyAuthorization.deserialize(serialized)
|
|
2070
|
+
expect(restored.scopes).toHaveLength(2)
|
|
2071
|
+
expect(restored.scopes?.[0]?.selector).toBe('0xa9059cbb')
|
|
2072
|
+
expect(restored.scopes?.[1]?.selector).toBe('0x095ea7b3')
|
|
2073
|
+
})
|
|
2074
|
+
|
|
2075
|
+
test('call scopes: mixed hex and signature selectors', () => {
|
|
2076
|
+
const authorization = KeyAuthorization.from({
|
|
2077
|
+
address,
|
|
2078
|
+
chainId: 1n,
|
|
2079
|
+
type: 'secp256k1',
|
|
2080
|
+
scopes: [
|
|
2081
|
+
{
|
|
2082
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
2083
|
+
selector: '0xa9059cbb',
|
|
2084
|
+
},
|
|
2085
|
+
{
|
|
2086
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
2087
|
+
selector: 'function approve(address,uint256)',
|
|
2088
|
+
},
|
|
2089
|
+
],
|
|
2090
|
+
})
|
|
2091
|
+
|
|
2092
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
2093
|
+
const restored = KeyAuthorization.deserialize(serialized)
|
|
2094
|
+
expect(restored.scopes?.[0]?.selector).toBe('0xa9059cbb')
|
|
2095
|
+
expect(restored.scopes?.[1]?.selector).toBe('0x095ea7b3')
|
|
2096
|
+
})
|
|
2097
|
+
|
|
2003
2098
|
test('toRpc/fromRpc roundtrip with period and scopes', () => {
|
|
2004
2099
|
const authorization = KeyAuthorization.from(
|
|
2005
2100
|
{
|
|
@@ -2016,7 +2111,7 @@ describe('toTuple', () => {
|
|
|
2016
2111
|
],
|
|
2017
2112
|
scopes: [
|
|
2018
2113
|
{
|
|
2019
|
-
|
|
2114
|
+
address: token,
|
|
2020
2115
|
selector: '0xa9059cbb',
|
|
2021
2116
|
recipients: ['0x1111111111111111111111111111111111111111'],
|
|
2022
2117
|
},
|
|
@@ -2031,7 +2126,7 @@ describe('toTuple', () => {
|
|
|
2031
2126
|
const restored = KeyAuthorization.fromRpc(rpc)
|
|
2032
2127
|
|
|
2033
2128
|
expect(restored.limits?.[0]?.period).toBe(2592000)
|
|
2034
|
-
expect(restored.scopes?.[0]?.
|
|
2129
|
+
expect(restored.scopes?.[0]?.address).toBe(token)
|
|
2035
2130
|
expect(restored.scopes?.[0]?.selector).toBe('0xa9059cbb')
|
|
2036
2131
|
expect(restored.scopes?.[0]?.recipients).toEqual([
|
|
2037
2132
|
'0x1111111111111111111111111111111111111111',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as AbiItem from '../core/AbiItem.js'
|
|
1
2
|
import type * as Address from '../core/Address.js'
|
|
2
3
|
import type * as Errors from '../core/Errors.js'
|
|
3
4
|
import * as Hash from '../core/Hash.js'
|
|
@@ -153,21 +154,25 @@ export type Tuple<signed extends boolean = boolean> = signed extends true
|
|
|
153
154
|
/**
|
|
154
155
|
* Call scope entry restricting which contract, selector, and recipients an access key can use.
|
|
155
156
|
*
|
|
156
|
-
* Multiple entries with the same `
|
|
157
|
+
* Multiple entries with the same `address` are grouped by target on the wire.
|
|
157
158
|
*
|
|
158
|
-
* - `{
|
|
159
|
-
* - `{
|
|
160
|
-
* - `{
|
|
159
|
+
* - `{ address }` = any selector on this contract
|
|
160
|
+
* - `{ address, selector }` = specific selector
|
|
161
|
+
* - `{ address, selector, recipients }` = selector + recipient constraint
|
|
161
162
|
*
|
|
162
163
|
* [TIP-1011 Specification](https://docs.tempo.xyz/protocol/transactions/tip-1011)
|
|
163
164
|
*/
|
|
164
165
|
export type Scope<addressType = Address.Address> = {
|
|
165
166
|
/** Target contract address. */
|
|
166
|
-
|
|
167
|
+
address: addressType
|
|
167
168
|
/**
|
|
168
|
-
* 4-byte function selector
|
|
169
|
+
* 4-byte function selector, or a human-readable ABI signature
|
|
170
|
+
* (e.g. `'transfer(address,uint256)'` or `'function transfer(address,uint256)'`).
|
|
171
|
+
*
|
|
172
|
+
* Signatures are encoded into a 4-byte selector automatically.
|
|
173
|
+
* Omit to allow any selector on this contract.
|
|
169
174
|
*/
|
|
170
|
-
selector?: Hex.Hex | undefined
|
|
175
|
+
selector?: Hex.Hex | string | undefined
|
|
171
176
|
/**
|
|
172
177
|
* Recipient allowlist for this selector (first ABI `address` argument).
|
|
173
178
|
*
|
|
@@ -352,8 +357,8 @@ export function from<
|
|
|
352
357
|
const auth = authorization as KeyAuthorization & {
|
|
353
358
|
limits?: readonly { token: TempoAddress.Address; limit: bigint }[]
|
|
354
359
|
scopes?: readonly {
|
|
355
|
-
|
|
356
|
-
selector?: Hex.Hex
|
|
360
|
+
address: TempoAddress.Address
|
|
361
|
+
selector?: Hex.Hex | string
|
|
357
362
|
recipients?: readonly TempoAddress.Address[]
|
|
358
363
|
}[]
|
|
359
364
|
}
|
|
@@ -372,7 +377,8 @@ export function from<
|
|
|
372
377
|
? {
|
|
373
378
|
scopes: auth.scopes.map((scope) => ({
|
|
374
379
|
...scope,
|
|
375
|
-
|
|
380
|
+
address: TempoAddress.resolve(scope.address),
|
|
381
|
+
selector: resolveSelector(scope.selector),
|
|
376
382
|
...(scope.recipients
|
|
377
383
|
? {
|
|
378
384
|
recipients: scope.recipients.map((r) =>
|
|
@@ -455,10 +461,10 @@ export function fromRpc(authorization: Rpc): Signed {
|
|
|
455
461
|
const scopes = allowedCalls
|
|
456
462
|
? allowedCalls.flatMap((callScope) => {
|
|
457
463
|
if (!callScope.selectorRules || callScope.selectorRules.length === 0)
|
|
458
|
-
return [{
|
|
464
|
+
return [{ address: callScope.target }] as Scope[]
|
|
459
465
|
return callScope.selectorRules.map(
|
|
460
466
|
(rule): Scope => ({
|
|
461
|
-
|
|
467
|
+
address: callScope.target,
|
|
462
468
|
selector: normalizeSelector(rule.selector),
|
|
463
469
|
...(rule.recipients && rule.recipients.length > 0
|
|
464
470
|
? { recipients: rule.recipients }
|
|
@@ -576,15 +582,15 @@ export function fromTuple<const tuple extends Tuple>(
|
|
|
576
582
|
...(typeof scopes !== 'undefined' && Array.isArray(scopes)
|
|
577
583
|
? {
|
|
578
584
|
scopes: scopes.flatMap((scopeTuple: any) => {
|
|
579
|
-
const [
|
|
585
|
+
const [address, selectorRules] = scopeTuple
|
|
580
586
|
// If no selector rules, this is an address-only scope
|
|
581
587
|
if (!Array.isArray(selectorRules) || selectorRules.length === 0)
|
|
582
|
-
return [{
|
|
588
|
+
return [{ address }]
|
|
583
589
|
// Flatten each selector rule into a separate scope entry
|
|
584
590
|
return selectorRules.map((ruleTuple: any) => {
|
|
585
591
|
const [selector, recipients] = ruleTuple
|
|
586
592
|
return {
|
|
587
|
-
|
|
593
|
+
address,
|
|
588
594
|
selector,
|
|
589
595
|
...(Array.isArray(recipients) && recipients.length > 0
|
|
590
596
|
? { recipients }
|
|
@@ -800,16 +806,16 @@ export function toRpc(authorization: Signed): Rpc {
|
|
|
800
806
|
const { address, scopes, chainId, expiry, limits, type, signature } =
|
|
801
807
|
authorization
|
|
802
808
|
|
|
803
|
-
// Group flat scopes by
|
|
809
|
+
// Group flat scopes by address into nested allowedCalls wire format
|
|
804
810
|
const allowedCalls = (() => {
|
|
805
811
|
if (!scopes) return undefined
|
|
806
812
|
const grouped = new Map<string, RpcSelectorRule[]>()
|
|
807
813
|
for (const scope of scopes) {
|
|
808
|
-
const key = scope.
|
|
814
|
+
const key = scope.address as string
|
|
809
815
|
if (!grouped.has(key)) grouped.set(key, [])
|
|
810
816
|
if (scope.selector) {
|
|
811
817
|
grouped.get(key)!.push({
|
|
812
|
-
selector: scope.selector
|
|
818
|
+
selector: resolveSelector(scope.selector)!,
|
|
813
819
|
...(scope.recipients && scope.recipients.length > 0
|
|
814
820
|
? { recipients: scope.recipients }
|
|
815
821
|
: {}),
|
|
@@ -899,7 +905,7 @@ export function toTuple<const authorization extends KeyAuthorization>(
|
|
|
899
905
|
if (limit.period && limit.period > 0) tuple.push(numberToHex(limit.period))
|
|
900
906
|
return tuple
|
|
901
907
|
})
|
|
902
|
-
// Group flat scopes by
|
|
908
|
+
// Group flat scopes by address for wire format
|
|
903
909
|
const callsValue = (() => {
|
|
904
910
|
if (!scopes) return undefined
|
|
905
911
|
const grouped = new Map<
|
|
@@ -907,20 +913,20 @@ export function toTuple<const authorization extends KeyAuthorization>(
|
|
|
907
913
|
[Hex.Hex, (readonly Address.Address[])[]][]
|
|
908
914
|
>()
|
|
909
915
|
for (const scope of scopes) {
|
|
910
|
-
const key = scope.
|
|
916
|
+
const key = scope.address as string
|
|
911
917
|
if (!grouped.has(key)) grouped.set(key, [])
|
|
912
918
|
if (scope.selector) {
|
|
913
919
|
grouped
|
|
914
920
|
.get(key)!
|
|
915
921
|
.push([
|
|
916
|
-
scope.selector
|
|
922
|
+
resolveSelector(scope.selector)!,
|
|
917
923
|
(scope.recipients ??
|
|
918
924
|
[]) as unknown as (readonly Address.Address[])[],
|
|
919
925
|
])
|
|
920
926
|
}
|
|
921
927
|
}
|
|
922
|
-
return [...grouped.entries()].map(([
|
|
923
|
-
|
|
928
|
+
return [...grouped.entries()].map(([address, selectorRules]) => [
|
|
929
|
+
address,
|
|
924
930
|
selectorRules.map(([selector, recipients]) => [selector, recipients]),
|
|
925
931
|
])
|
|
926
932
|
})()
|
|
@@ -971,3 +977,11 @@ function normalizeSelector(selector: Hex.Hex | number[]): Hex.Hex {
|
|
|
971
977
|
return Hex.fromBytes(new Uint8Array(selector)) as Hex.Hex
|
|
972
978
|
return selector
|
|
973
979
|
}
|
|
980
|
+
|
|
981
|
+
function resolveSelector(
|
|
982
|
+
selector: Hex.Hex | string | undefined,
|
|
983
|
+
): Hex.Hex | undefined {
|
|
984
|
+
if (!selector) return undefined
|
|
985
|
+
if (selector.startsWith('0x')) return selector as Hex.Hex
|
|
986
|
+
return AbiItem.getSelector(selector)
|
|
987
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type * as Block from '../core/Block.js'
|
|
2
|
+
import type * as BlockOverrides from '../core/BlockOverrides.js'
|
|
3
|
+
import type * as Hex from '../core/Hex.js'
|
|
4
|
+
import type * as Log from '../core/Log.js'
|
|
5
|
+
import type * as RpcSchema from '../core/RpcSchema.js'
|
|
6
|
+
import type * as StateOverrides from '../core/StateOverrides.js'
|
|
7
|
+
import type * as TransactionRequest from './TransactionRequest.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Union of all JSON-RPC Methods for the `tempo_` namespace.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts twoslash
|
|
14
|
+
* import { RpcSchema } from 'ox/tempo'
|
|
15
|
+
*
|
|
16
|
+
* type Schema = RpcSchema.Tempo
|
|
17
|
+
* // ^?
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
*
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
*
|
|
25
|
+
*
|
|
26
|
+
*
|
|
27
|
+
*
|
|
28
|
+
*
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export type Tempo = RpcSchema.From<{
|
|
32
|
+
Request: {
|
|
33
|
+
method: 'tempo_simulateV1'
|
|
34
|
+
params: [
|
|
35
|
+
{
|
|
36
|
+
blockStateCalls: readonly {
|
|
37
|
+
blockOverrides?: BlockOverrides.Rpc | undefined
|
|
38
|
+
calls?: readonly TransactionRequest.Rpc[] | undefined
|
|
39
|
+
stateOverrides?: StateOverrides.Rpc | undefined
|
|
40
|
+
}[]
|
|
41
|
+
returnFullTransactions?: boolean | undefined
|
|
42
|
+
traceTransfers?: boolean | undefined
|
|
43
|
+
validation?: boolean | undefined
|
|
44
|
+
},
|
|
45
|
+
block: Block.Number<Hex.Hex> | Block.Tag | Block.Hash | Block.Identifier,
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
ReturnType: {
|
|
49
|
+
blocks: readonly (Block.Rpc & {
|
|
50
|
+
calls?:
|
|
51
|
+
| readonly {
|
|
52
|
+
error?:
|
|
53
|
+
| {
|
|
54
|
+
data?: Hex.Hex | undefined
|
|
55
|
+
code: number
|
|
56
|
+
message: string
|
|
57
|
+
}
|
|
58
|
+
| undefined
|
|
59
|
+
logs?: readonly Log.Rpc[] | undefined
|
|
60
|
+
gasUsed: Hex.Hex
|
|
61
|
+
returnData: Hex.Hex
|
|
62
|
+
status: Hex.Hex
|
|
63
|
+
}[]
|
|
64
|
+
| undefined
|
|
65
|
+
})[]
|
|
66
|
+
tokenMetadata: {
|
|
67
|
+
[address: Hex.Hex]: {
|
|
68
|
+
name: string
|
|
69
|
+
symbol: string
|
|
70
|
+
currency: string
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}>
|