Skip to content
LogoLogo

accessKey.signAuthorization

Signs a key authorization for an access key. The action resolves any required chain state before signing, but does not send a transaction. For a coordinated multisig, each call stores one owner approval and returns the signed authorization with the current operation under multisig.

Usage

import { Account, P256 } from 'viem/tempo'
import { client } from './viem.config'
 
// 1. Define root account
const account = Account.fromSecp256k1('0x...')
 
// 2. Define access key attached to the root account
const accessKey = Account.fromP256(P256.randomPrivateKey(), {
  access: account,
})
 
// 3. Sign the key authorization
const keyAuthorization = await client.accessKey.signAuthorization({
  account,
  accessKey,
})

Coordinated Multisig Approvals

Pass a multisig account with the first owner's approval. Later owners continue the operation using its hash.

import { Account, P256 } from 'viem/tempo'
import { client } from './viem.config'
 
const owner_1 = Account.fromSecp256k1(
  '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
)
const owner_2 = Account.fromSecp256k1(
  '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
)
const multisig = Account.fromMultisig({
  address: 'infer',
  owners: [owner_1.address, owner_2.address],
  threshold: 2,
})
const accessKey = Account.fromP256(P256.randomPrivateKey(), {
  access: multisig,
})
 
const pending = await client.accessKey.signAuthorization({
  accessKey,
  account: multisig,
  owner: owner_1,
})
 
const success = await client.accessKey.signAuthorization({
  hash: pending.hash,
  owner: owner_2,
})

With Periodic Spending Limits

Use the period field on limits to set a recurring spending cap that resets after the given number of seconds:

import { parseUnits } from 'viem'
import { Account, Period, P256 } from 'viem/tempo'
import { client } from './viem.config'
 
const account = Account.fromSecp256k1('0x...')
const accessKey = Account.fromP256(P256.randomPrivateKey(), {
  access: account,
})
 
const keyAuthorization = await client.accessKey.signAuthorization({
  account,
  accessKey,
  limits: [ 
    { 
      token: '0x20c0000000000000000000000000000000000001', 
      limit: parseUnits('1000', 6), 
      period: Period.months(1), // resets every month
    }, 
  ], 
})

With Call Scopes

Use scopes to restrict which contracts and functions the access key can call:

import { parseUnits } from 'viem'
import { Account, P256 } from 'viem/tempo'
import { client } from './viem.config'
 
const account = Account.fromSecp256k1('0x...')
const accessKey = Account.fromP256(P256.randomPrivateKey(), {
  access: account,
})
 
const keyAuthorization = await client.accessKey.signAuthorization({
  account,
  accessKey,
  limits: [ 
    { 
      token: '0x20c0000000000000000000000000000000000001', 
      limit: parseUnits('10000', 6), 
    }, 
  ], 
  scopes: [ 
    { 
      address: '0x20c0000000000000000000000000000000000001', 
      selector: 'transfer(address,uint256)', // or "0xa9059cbb"
      recipients: ['0xcafebabecafebabecafebabecafebabecafebabe'], // optional
    }, 
  ], 
})

Authorize Public Keys

Instead of passing an AccessKeyAccount, you can sign an authorization for a key by its public key or address directly:

import { Account, P256 } from 'viem/tempo'
import { client } from './viem.config'
 
const account = Account.fromSecp256k1('0x...')
 
// Sign authorization by public key
const keyAuthorization = await client.accessKey.signAuthorization({ 
  account, 
  accessKey: { 
    publicKey: '0x...', 
    type: 'p256', 
  }, 
}) 

You can also sign by address:

import { Account } from 'viem/tempo'
import { client } from './viem.config'
 
const account = Account.fromSecp256k1('0x...')
 
// Sign authorization by address
const keyAuthorization = await client.accessKey.signAuthorization({ 
  account, 
  accessKey: { 
    address: '0x...', 
    type: 'p256', 
  }, 
}) 

Submitting the Authorization

The signed keyAuthorization can be attached to any write action.

// Authorize the key alongside a transfer, sent with the access key
const { receipt } = await client.token.transferSync({
  account: accessKey,
  token: '0x20c0000000000000000000000000000000000001',
  to: '0xcafebabecafebabecafebabecafebabecafebabe',
  amount: 100n,
  keyAuthorization,
})

Return Type

type ReturnType =
  | KeyAuthorization.Signed
  | (KeyAuthorization.Signed & {
      hash: Hex
      multisig: MultisigOperation.KeyAuthorizationOperation
      status: 'pending' | 'success'
    })

Local signing returns a signed key authorization that can be passed to any write action. Coordinated signing also returns the operation hash, status, and multisig details. A successful result can be passed directly to any write action as its keyAuthorization.

Parameters

account

  • Type: RootAccount | MultisigAccount

The account authorizing the access key. For coordinated signing, pass the multisig account here.

accessKey

  • Type: { accessKeyAddress: Address; keyType: string } | { address: Address; type: string } | { publicKey: Hex; type: string }

The access key to authorize. Accepts an AccessKeyAccount, or an object with { address, type } or { publicKey, type }.

admin (optional)

  • Type: boolean

Whether to authorize the key as an admin key. Admin keys are unrestricted and can manage the account's other access keys; expiry, limits, and scopes are ignored. Requires the T6 hardfork (TIP-1049).

expiry (optional)

  • Type: number

Unix timestamp when the key expires.

hash

  • Type: Hex

The operation hash returned by the first coordinated approval. Pass it instead of the initial authorization fields when adding another owner approval.

fundingPolicy (optional)

  • Type: true | bigint | FundingPolicy.Inline

Use an existing policy ID, an inline { admins, rules } policy, or true to select the funding handler's configured policyId. The default is resolved before signing; explicit IDs and inline policies are unchanged.

The policy's administrators can change its rules for all attached access keys. Relay.funding supplies current registered policyRules when filling payments.

See access key funding for a complete example.

limits (optional)

  • Type: { token: Address; limit: bigint; period?: number }[]

Spending limits per token. Optionally include period (in seconds) to make the limit periodic. It resets after each period.

owner

  • Type: RootAccount | MultisigAccount

The local owner adding a coordinated approval. Passing owner with a multisig account starts a coordinated operation. Later owners pass owner with the operation hash.

scopes (optional)

  • Type: { address: Address; selector?: Hex | string; recipients?: Address[] }[]

Call scopes restricting which contracts/selectors this key can call.

witness (optional)

  • Type: Hex

Optional 32-byte witness bound into the authorization's signing hash. Can be burned onchain via accessKey.burnWitness to invalidate the authorization before it is submitted (TIP-1053).