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,
})import { Account, createClient } from 'viem/tempo'
export const client = createClient({
account: Account.fromSecp256k1('0x...'),
})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,
})import { createClient, http, Relay, withRelay } from 'viem/tempo'
import { store } from './store.db'
export const client = createClient({
transport: withRelay(http(), {
plugins: [Relay.multisig({ store })],
}),
})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
},
],
})import { parseUnits } from 'viem'
import { Account, P256, Scopes } 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: [
Scopes.tip20('0x20c0000000000000000000000000000000000001')
.transfer({
recipients: ['0xcafebabecafebabecafebabecafebabecafebabe'],
}),
],
})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).