@tempoxyz/auth 0.0.0-pr-29.sha-cd99b2f → 0.0.0-pr-28.sha-47f5dbe

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/README.md CHANGED
@@ -6,8 +6,12 @@ Every sign-in returns the same `Authorization`. Send transactions with its `acco
6
6
 
7
7
  ```ts
8
8
  import { Actions, Auth } from '@tempoxyz/auth'
9
- import { Addresses, createClient, Expiry, Scopes } from 'viem/tempo'
10
- import { tempoTestnet } from 'viem/tempo/chains'
9
+ import { createClient, Expiry, Scopes } from 'viem/tempo'
10
+ import { tempo, tempoTestnet } from 'viem/tempo/chains'
11
+ import * as Tokens from 'viem/tokens'
12
+
13
+ // OUSD has its mainnet address on every Tempo chain.
14
+ const ousd = Tokens.ousd(tempo.id).address
11
15
 
12
16
  const auth = Auth.create({
13
17
  chainId: tempoTestnet.id,
@@ -16,14 +20,14 @@ const auth = Auth.create({
16
20
  })
17
21
  const client = createClient({
18
22
  chain: tempoTestnet,
19
- feeToken: Addresses.pathUsd,
23
+ feeToken: ousd,
20
24
  })
21
25
 
22
26
  const authorization = await Actions.authorize(auth, {
23
27
  permissions: {
24
28
  expiry: Expiry.days(1),
25
- limits: [{ limit: 10_000_000n, token: Addresses.pathUsd }],
26
- scopes: [Scopes.tip20(Addresses.pathUsd).transfer()],
29
+ limits: [{ limit: 10_000_000n, token: ousd }],
30
+ scopes: [Scopes.tip20(ousd).transfer()],
27
31
  },
28
32
  })
29
33
 
@@ -31,7 +35,7 @@ await client.token.transferSync({
31
35
  account: authorization!.account,
32
36
  amount: 10_000n,
33
37
  to: '0x…',
34
- token: Addresses.pathUsd,
38
+ token: ousd,
35
39
  })
36
40
  ```
37
41
 
@@ -50,14 +54,14 @@ The CLI device grant needs neither. It signs in as Tempo Auth's own `tempo-cli`
50
54
 
51
55
  ## Access keys
52
56
 
53
- Each sign-in creates a key for the app and asks Tempo Auth to authorize it on the user's Tempo Account. The `permissions` option says what the key may do, with viem's `Expiry` and `Scopes` helpers:
57
+ Each sign-in creates a key for the app and asks Tempo Auth to authorize it on the user's Tempo Account. The optional `permissions` option says what the key may do, with viem's `Expiry` and `Scopes` helpers. Tempo Auth fills every field it leaves out with the headless ceiling:
54
58
 
55
- | Field | Meaning |
56
- | --------- | ----------------------------------------------------------------------------- |
57
- | `chainId` | Optional: the chain the key acts on. Defaults to the instance's `chainId` |
58
- | `expiry` | When the key expires, in Unix seconds, such as `Expiry.days(1)` |
59
- | `limits` | One-time spending limits per token, such as `[{ limit: 10_000_000n, token }]` |
60
- | `scopes` | The calls the key may make, such as `[Scopes.tip20(token).transfer()]` |
59
+ | Field | Meaning |
60
+ | --------- | ----------------------------------------------------------------------------------------------------------- |
61
+ | `chainId` | The chain the key acts on. Defaults to the instance's `chainId` |
62
+ | `expiry` | When the key expires, in Unix seconds, such as `Expiry.days(1)`. Defaults to a year |
63
+ | `limits` | One-time spending limits per token, such as `[{ limit: 10_000_000n, token }]`. Defaults to about $1,000 of each token the `scopes` call, or of OUSD |
64
+ | `scopes` | The calls the key may make, such as `[Scopes.tip20(token).transfer()]`. Defaults to transfers of each token the key limits |
61
65
 
62
66
  In a browser, the key is a non-extractable WebCrypto P256 key, so no script can read its private key. A CLI, a native app, or a backend gets a secp256k1 key, which it stores as a string.
63
67
 
@@ -65,10 +69,10 @@ To authorize a key the app already holds, pass it as `accessKey`, a viem account
65
69
 
66
70
  ```ts
67
71
  const accessKey = Account.fromWebCryptoP256(keyPair, { access: tempoAccount })
68
- await Actions.authorize(auth, { accessKey, permissions })
72
+ await Actions.authorize(auth, { accessKey })
69
73
  ```
70
74
 
71
- Flows without a Tempo Auth page (`authorize`, `email.signIn`) must stay within Tempo Auth's ceiling, about $1,000 per token. Flows with a page (`redirect.start`, `redirect.createUrl`, `device.authorize`) show the limits to the user, who approves them, so they may go beyond it.
75
+ Flows without a Tempo Auth page (`authorize`, `email.signIn`) must stay within Tempo Auth's ceiling: about $1,000 per token, for at most a year. Flows with a page (`redirect.start`, `redirect.createUrl`, `device.authorize`) show the limits to the user, who approves them, so they may go beyond it.
72
76
 
73
77
  The returned `account` attaches the key's authorization to its first transaction, which registers the key on chain.
74
78
 
@@ -80,11 +84,11 @@ For a browser app that renders its own email form. The page calls Tempo Auth wit
80
84
 
81
85
  ```ts
82
86
  // A user already signed in to Tempo Auth, from any app, needs no form.
83
- const authorization = await Actions.authorize(auth, { permissions })
87
+ const authorization = await Actions.authorize(auth)
84
88
 
85
89
  // Otherwise, sign in with an emailed code.
86
90
  await Actions.email.sendCode(auth, { email })
87
- const result = await Actions.email.signIn(auth, { code, email, permissions })
91
+ const result = await Actions.email.signIn(auth, { code, email })
88
92
 
89
93
  // An address that requires SSO continues at its connection, and returns to this page.
90
94
  if ('step' in result) Actions.provider.signIn(auth, { url: result.step.url })
@@ -102,7 +106,7 @@ Actions.provider.signIn(auth, { provider: 'google' })
102
106
  For a browser app without its own sign-in UI. The browser leaves for Tempo Auth's sign-in page, which shows the key's limits, and returns with a code.
103
107
 
104
108
  ```ts
105
- await Actions.redirect.start(auth, { permissions })
109
+ await Actions.redirect.start(auth)
106
110
 
107
111
  // On the page the browser returns to, and on every load:
108
112
  const authorization = await Actions.redirect.complete(auth)
@@ -125,12 +129,10 @@ const auth = Auth.create({
125
129
 
126
130
  // Your own sign-in UI, as in a browser.
127
131
  await Actions.email.sendCode(auth, { email })
128
- const result = await Actions.email.signIn(auth, { code, email, permissions })
132
+ const result = await Actions.email.signIn(auth, { code, email })
129
133
 
130
134
  // Or Tempo Auth's pages, which also offer Google and SSO.
131
- const { pending, url } = await Actions.redirect.createUrl(auth, {
132
- permissions,
133
- })
135
+ const { pending, url } = await Actions.redirect.createUrl(auth)
134
136
  const session = await WebBrowser.openAuthSessionAsync(url, auth.redirectUri)
135
137
  if (session.type === 'success')
136
138
  authorization = await Actions.redirect.handleCallback(auth, {
@@ -150,7 +152,6 @@ const auth = Auth.create({ clientId, clientSecret, url })
150
152
 
151
153
  // GET /auth/start
152
154
  const { pending, url } = await Actions.redirect.createUrl(auth, {
153
- permissions,
154
155
  redirectUri: 'https://app.example/auth/callback',
155
156
  })
156
157
  // Keep `pending` in an encrypted, HttpOnly cookie, then redirect to `url`.
@@ -169,7 +170,6 @@ For a command-line tool. The user approves a code in any browser, and the CLI wa
169
170
  ```ts
170
171
  const device = await Actions.device.authorize(auth, {
171
172
  device: os.hostname(),
172
- permissions,
173
173
  })
174
174
  console.log(
175
175
  `Open ${device.verificationUriComplete} and confirm ${device.userCode}.`,
@@ -189,7 +189,6 @@ await Actions.authorize(auth, {
189
189
  accessKey: Account.fromWebCryptoP256(keyPair, {
190
190
  access: tempoAccount.address,
191
191
  }),
192
- permissions,
193
192
  })
194
193
  ```
195
194
 
@@ -220,7 +219,7 @@ A request Tempo Auth refuses throws `Auth.RequestError`, with its `status` and `
220
219
 
221
220
  ```ts
222
221
  try {
223
- await Actions.email.signIn(auth, { code, email, permissions })
222
+ await Actions.email.signIn(auth, { code, email })
224
223
  } catch (error) {
225
224
  if (error instanceof Auth.RequestError && error.status === 401)
226
225
  showWrongCode()
@@ -244,22 +243,22 @@ try {
244
243
 
245
244
  ### `Actions`
246
245
 
247
- Each sign-in flow has its own namespace. The actions every flow shares sit at the top level. Every action that takes `permissions` also takes an optional `accessKey`.
246
+ Each sign-in flow has its own namespace. The actions every flow shares sit at the top level. Every action that creates a key also takes optional `accessKey` and `permissions`.
248
247
 
249
248
  | Action | Returns |
250
249
  | -------------------------------------------------------- | -------------------------------------------------------------------------- |
251
- | `authorize(auth, { permissions })` | An `Authorization` for a user already signed in, or `undefined` |
250
+ | `authorize(auth)` | An `Authorization` for a user already signed in, or `undefined` |
252
251
  | `refresh(auth, { refreshToken })` | New `Tokens` |
253
252
  | `signOut(auth)` | Nothing. The user's Tempo Auth session ends |
254
- | `device.authorize(auth, { device, permissions })` | The code to show and a `wait()` that resolves with an `Authorization` |
253
+ | `device.authorize(auth, { device })` | The code to show and a `wait()` that resolves with an `Authorization` |
255
254
  | `email.sendCode(auth, { email })` | Nothing. Tempo Auth emails a code |
256
- | `email.signIn(auth, { code, email, permissions })` | An `Authorization`, or the `step` the address requires first |
255
+ | `email.signIn(auth, { code, email })` | An `Authorization`, or the `step` the address requires first |
257
256
  | `provider.list(auth)` | The OAuth providers Tempo Auth offers, as `{ id, name }` |
258
257
  | `provider.signIn(auth, { provider } \| { url })` | Nothing. The browser leaves for the provider or SSO connection |
259
258
  | `redirect.complete(auth, { accessKey })` | The `Authorization` when the page is a redirect's callback, or `undefined` |
260
- | `redirect.createUrl(auth, { permissions, redirectUri })` | The `url` to send the browser to, and the `pending` state to keep |
259
+ | `redirect.createUrl(auth, { redirectUri })` | The `url` to send the browser to, and the `pending` state to keep |
261
260
  | `redirect.handleCallback(auth, { pending, url })` | The `Authorization` for a redirect's callback |
262
- | `redirect.start(auth, { permissions })` | Nothing. The browser leaves for Tempo Auth's pages |
261
+ | `redirect.start(auth)` | Nothing. The browser leaves for Tempo Auth's pages |
263
262
  | `tempoAccount.create(auth)` | Another Tempo Account for the signed-in user |
264
263
  | `tempoAccount.list(auth)` | The signed-in user's Tempo Accounts, the default first |
265
264
 
package/dist/Actions.d.ts CHANGED
@@ -20,11 +20,11 @@ export * as tempoAccount from './actions/tempoAccount.ts';
20
20
  *
21
21
  * @example
22
22
  * ```ts
23
- * const authorization = await Actions.authorize(auth, { permissions })
23
+ * const authorization = await Actions.authorize(auth)
24
24
  * if (!authorization) showSignIn()
25
25
  * ```
26
26
  */
27
- export declare function authorize(auth: Auth, options: authorize.Options): Promise<authorize.ReturnType>;
27
+ export declare function authorize(auth: Auth, options?: authorize.Options): Promise<authorize.ReturnType>;
28
28
  export declare namespace authorize {
29
29
  type Options = {
30
30
  /**
@@ -32,8 +32,8 @@ export declare namespace authorize {
32
32
  * defaults to the user's first. Defaults to a new key.
33
33
  */
34
34
  accessKey?: Account.Account | undefined;
35
- /** What the key may do. It must fit the headless ceiling. */
36
- permissions: Permissions;
35
+ /** What the key may do. It must fit the headless ceiling, which fills what it leaves out. */
36
+ permissions?: Permissions | undefined;
37
37
  };
38
38
  /** The authorization, or `undefined` without a session. */
39
39
  type ReturnType = Authorization | undefined;
package/dist/Actions.js CHANGED
@@ -13,11 +13,11 @@ export * as tempoAccount from './actions/tempoAccount.js';
13
13
  *
14
14
  * @example
15
15
  * ```ts
16
- * const authorization = await Actions.authorize(auth, { permissions })
16
+ * const authorization = await Actions.authorize(auth)
17
17
  * if (!authorization) showSignIn()
18
18
  * ```
19
19
  */
20
- export async function authorize(auth, options) {
20
+ export async function authorize(auth, options = {}) {
21
21
  // Checking the session first answers a visitor without one with no failed request.
22
22
  const session = await Api.json(await (auth.fetch ?? fetch)(new URL('/api/auth/session', auth.url), {
23
23
  credentials: 'include',
package/dist/Auth.js CHANGED
@@ -6,8 +6,11 @@
6
6
  * @example
7
7
  * ```ts
8
8
  * import { Actions, Auth } from '@tempoxyz/auth'
9
- * import { Addresses, Expiry, Scopes } from 'viem/tempo'
10
- * import { tempoTestnet } from 'viem/tempo/chains'
9
+ * import { Expiry, Scopes } from 'viem/tempo'
10
+ * import { tempo, tempoTestnet } from 'viem/tempo/chains'
11
+ * import * as Tokens from 'viem/tokens'
12
+ *
13
+ * const ousd = Tokens.ousd(tempo.id).address
11
14
  *
12
15
  * const auth = Auth.create({
13
16
  * chainId: tempoTestnet.id,
@@ -18,8 +21,8 @@
18
21
  * const authorization = await Actions.authorize(auth, {
19
22
  * permissions: {
20
23
  * expiry: Expiry.days(1),
21
- * limits: [{ limit: 10_000_000n, token: Addresses.pathUsd }],
22
- * scopes: [Scopes.tip20(Addresses.pathUsd).transfer()],
24
+ * limits: [{ limit: 10_000_000n, token: ousd }],
25
+ * scopes: [Scopes.tip20(ousd).transfer()],
23
26
  * },
24
27
  * })
25
28
  * ```
@@ -3,12 +3,19 @@
3
3
  * @module
4
4
  */
5
5
  import type { KeyAuthorization } from 'ox/tempo';
6
- /** What an app's access key may do, as viem's `accessKey.authorize` takes it. */
7
- export type Permissions = Pick<KeyAuthorization.KeyAuthorization, 'limits' | 'scopes'> & {
6
+ /**
7
+ * What an app's access key may do, as viem's `accessKey.authorize` takes it. Tempo Auth fills what
8
+ * it leaves out with the headless ceiling.
9
+ */
10
+ export type Permissions = {
8
11
  /** The chain the key acts on, such as `tempoTestnet.id`. Defaults to the instance's `chainId`. */
9
12
  chainId?: number | undefined;
10
- /** Unix seconds. viem's `Expiry` builds one, such as `Expiry.days(1)`. */
11
- expiry: number;
13
+ /** Unix seconds. viem's `Expiry` builds one, such as `Expiry.days(1)`. Defaults to a year from now. */
14
+ expiry?: number | undefined;
15
+ /** How much of each token the key may spend. Defaults to about $1,000 of each token it calls, or of OUSD. */
16
+ limits?: KeyAuthorization.KeyAuthorization['limits'];
17
+ /** The calls the key may make. Defaults to transfers of each token it limits. */
18
+ scopes?: KeyAuthorization.KeyAuthorization['scopes'];
12
19
  };
13
20
  /**
14
21
  * Instantiates a {@link Permissions}.
@@ -17,8 +24,8 @@ export type Permissions = Pick<KeyAuthorization.KeyAuthorization, 'limits' | 'sc
17
24
  * ```ts
18
25
  * const permissions = Permissions.from({
19
26
  * expiry: Expiry.days(1),
20
- * limits: [{ limit: 10_000_000n, token: Addresses.pathUsd }],
21
- * scopes: [Scopes.tip20(Addresses.pathUsd).transfer()],
27
+ * limits: [{ limit: 10_000_000n, token: ousd }],
28
+ * scopes: [Scopes.tip20(ousd).transfer()],
22
29
  * })
23
30
  * ```
24
31
  */
@@ -5,8 +5,8 @@
5
5
  * ```ts
6
6
  * const permissions = Permissions.from({
7
7
  * expiry: Expiry.days(1),
8
- * limits: [{ limit: 10_000_000n, token: Addresses.pathUsd }],
9
- * scopes: [Scopes.tip20(Addresses.pathUsd).transfer()],
8
+ * limits: [{ limit: 10_000_000n, token: ousd }],
9
+ * scopes: [Scopes.tip20(ousd).transfer()],
10
10
  * })
11
11
  * ```
12
12
  */
@@ -8,7 +8,7 @@ import type { Permissions } from '../Permissions.ts';
8
8
  *
9
9
  * @example
10
10
  * ```ts
11
- * const device = await Actions.device.authorize(auth, { device: Os.hostname(), permissions })
11
+ * const device = await Actions.device.authorize(auth, { device: Os.hostname() })
12
12
  * console.log(`Open ${device.verificationUriComplete}`)
13
13
  * const authorization = await device.wait()
14
14
  * ```
@@ -23,8 +23,8 @@ export declare namespace authorize {
23
23
  accessKey?: Account.Account | undefined;
24
24
  /** The name the approval page shows, such as the machine's hostname. */
25
25
  device: string;
26
- /** What the CLI's key may do. The approval page shows it beside the device. */
27
- permissions: Permissions;
26
+ /** What the CLI's key may do. The approval page shows it beside the device, and the headless ceiling fills what it leaves out. */
27
+ permissions?: Permissions | undefined;
28
28
  };
29
29
  type ReturnType = {
30
30
  /** Seconds until the code expires. */
@@ -8,7 +8,7 @@ import { request } from '../internal/request.js';
8
8
  *
9
9
  * @example
10
10
  * ```ts
11
- * const device = await Actions.device.authorize(auth, { device: Os.hostname(), permissions })
11
+ * const device = await Actions.device.authorize(auth, { device: Os.hostname() })
12
12
  * console.log(`Open ${device.verificationUriComplete}`)
13
13
  * const authorization = await device.wait()
14
14
  * ```
@@ -28,7 +28,7 @@ export declare namespace sendCode {
28
28
  *
29
29
  * @example
30
30
  * ```ts
31
- * const result = await Actions.email.signIn(auth, { code, email, permissions })
31
+ * const result = await Actions.email.signIn(auth, { code, email })
32
32
  * if ('step' in result) Actions.provider.signIn(auth, { url: result.step.url })
33
33
  * ```
34
34
  */
@@ -44,8 +44,8 @@ export declare namespace signIn {
44
44
  code: string;
45
45
  /** The address the code was sent to. */
46
46
  email: string;
47
- /** What the key may do. It must fit the headless ceiling. */
48
- permissions: Permissions;
47
+ /** What the key may do. It must fit the headless ceiling, which fills what it leaves out. */
48
+ permissions?: Permissions | undefined;
49
49
  };
50
50
  /** The authorization, or the step the address requires first. */
51
51
  type ReturnType = Authorization | {
@@ -18,7 +18,7 @@ export async function sendCode(auth, options) {
18
18
  *
19
19
  * @example
20
20
  * ```ts
21
- * const result = await Actions.email.signIn(auth, { code, email, permissions })
21
+ * const result = await Actions.email.signIn(auth, { code, email })
22
22
  * if ('step' in result) Actions.provider.signIn(auth, { url: result.step.url })
23
23
  * ```
24
24
  */
@@ -11,7 +11,7 @@ import type { Permissions } from '../Permissions.ts';
11
11
  * ```ts
12
12
  * const authorization =
13
13
  * (await Actions.redirect.complete(auth)) ??
14
- * (await Actions.authorize(auth, { permissions }))
14
+ * (await Actions.authorize(auth))
15
15
  * ```
16
16
  */
17
17
  export declare function complete(auth: Auth, options?: complete.Options): Promise<complete.ReturnType>;
@@ -31,14 +31,13 @@ export declare namespace complete {
31
31
  * @example
32
32
  * ```ts
33
33
  * const { pending, url } = await Actions.redirect.createUrl(auth, {
34
- * permissions,
35
34
  * redirectUri: 'https://app.example/auth/callback',
36
35
  * })
37
36
  * await seal(c, 'oauth', pending)
38
37
  * return c.redirect(url)
39
38
  * ```
40
39
  */
41
- export declare function createUrl(auth: Auth, options: createUrl.Options): Promise<createUrl.ReturnType>;
40
+ export declare function createUrl(auth: Auth, options?: createUrl.Options): Promise<createUrl.ReturnType>;
42
41
  export declare namespace createUrl {
43
42
  type Options = {
44
43
  /**
@@ -46,8 +45,8 @@ export declare namespace createUrl {
46
45
  * defaults to the user's first. Defaults to a new key, whose material `pending` keeps.
47
46
  */
48
47
  accessKey?: Account.Account | undefined;
49
- /** What the key may do. Tempo Auth's pages show it, and the user approves it. */
50
- permissions: Permissions;
48
+ /** What the key may do. Tempo Auth's pages show it, and the headless ceiling fills what it leaves out. */
49
+ permissions?: Permissions | undefined;
51
50
  /** Where Tempo Auth redirects back to. Defaults to the instance's `redirectUri`. */
52
51
  redirectUri?: string | undefined;
53
52
  };
@@ -87,10 +86,10 @@ export declare namespace handleCallback {
87
86
  *
88
87
  * @example
89
88
  * ```ts
90
- * await Actions.redirect.start(auth, { permissions })
89
+ * await Actions.redirect.start(auth)
91
90
  * ```
92
91
  */
93
- export declare function start(auth: Auth, options: start.Options): Promise<void>;
92
+ export declare function start(auth: Auth, options?: start.Options): Promise<void>;
94
93
  export declare namespace start {
95
94
  type Options = {
96
95
  /**
@@ -98,7 +97,7 @@ export declare namespace start {
98
97
  * key, which `storage` keeps until the browser returns.
99
98
  */
100
99
  accessKey?: Account.Account | undefined;
101
- /** What the key may do. Tempo Auth's pages show it, and the user approves it. */
102
- permissions: Permissions;
100
+ /** What the key may do. Tempo Auth's pages show it, and the headless ceiling fills what it leaves out. */
101
+ permissions?: Permissions | undefined;
103
102
  };
104
103
  }
@@ -19,7 +19,7 @@ import * as Pending from '../Pending.js';
19
19
  * ```ts
20
20
  * const authorization =
21
21
  * (await Actions.redirect.complete(auth)) ??
22
- * (await Actions.authorize(auth, { permissions }))
22
+ * (await Actions.authorize(auth))
23
23
  * ```
24
24
  */
25
25
  export function complete(auth, options = {}) {
@@ -53,14 +53,13 @@ export function complete(auth, options = {}) {
53
53
  * @example
54
54
  * ```ts
55
55
  * const { pending, url } = await Actions.redirect.createUrl(auth, {
56
- * permissions,
57
56
  * redirectUri: 'https://app.example/auth/callback',
58
57
  * })
59
58
  * await seal(c, 'oauth', pending)
60
59
  * return c.redirect(url)
61
60
  * ```
62
61
  */
63
- export async function createUrl(auth, options) {
62
+ export async function createUrl(auth, options = {}) {
64
63
  const redirectUri = options.redirectUri ?? auth.redirectUri ?? `${window.location.origin}/`;
65
64
  const key = await AccessKey.resolve(options.accessKey);
66
65
  const pending = Pending.from({
@@ -129,10 +128,10 @@ export async function handleCallback(auth, options) {
129
128
  *
130
129
  * @example
131
130
  * ```ts
132
- * await Actions.redirect.start(auth, { permissions })
131
+ * await Actions.redirect.start(auth)
133
132
  * ```
134
133
  */
135
- export async function start(auth, options) {
134
+ export async function start(auth, options = {}) {
136
135
  const { pending, url } = await createUrl(auth, options);
137
136
  await storage(auth).setItem(storageKey, pending);
138
137
  window.location.assign(url);
@@ -7,14 +7,14 @@ import type { Permissions } from '../Permissions.ts';
7
7
  */
8
8
  export declare function request(auth: Auth, options: {
9
9
  accessKey: Account.Account;
10
- permissions: Permissions;
10
+ permissions?: Permissions | undefined;
11
11
  }): {
12
12
  client_id: string;
13
13
  keyAuthorization: {
14
14
  account?: `0x${string}`;
15
15
  address: `0x${string}`;
16
16
  chainId: `0x${string}`;
17
- expiry: number;
17
+ expiry: number | undefined;
18
18
  keyType: "p256" | "secp256k1" | "webAuthn";
19
19
  limits: {
20
20
  limit: `0x${string}`;
@@ -9,7 +9,7 @@ import { Hex } from 'ox';
9
9
  * key account names its Tempo Account through `access`, and a plain key leaves it to Tempo Auth.
10
10
  */
11
11
  export function request(auth, options) {
12
- const { accessKey, permissions } = options;
12
+ const { accessKey, permissions = {} } = options;
13
13
  return {
14
14
  client_id: auth.clientId,
15
15
  keyAuthorization: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tempoxyz/auth",
3
- "version": "0.0.0-pr-29.sha-cd99b2f",
3
+ "version": "0.0.0-pr-28.sha-47f5dbe",
4
4
  "description": "Signs users in to Tempo through Tempo Auth, and returns viem access key accounts on their Tempo Accounts.",
5
5
  "type": "module",
6
6
  "exports": {