Documentation
¶
Overview ¶
Package keychain provides access key management and signing for Tempo transactions.
The AccountKeychain precompile manages authorized Access Keys for accounts, enabling Root Keys (e.g., passkeys) to provision scoped "secondary" Access Keys with expiry timestamps, per-TIP20 token spending limits, and call scope restrictions (per-contract, per-selector, and per-recipient filtering). T5 adds TIP-1053 witness APIs for authorizing keys with a bytes32 witness, burning key-authorization witnesses, and checking whether a witness has been burned for an account. T6 adds TIP-1049 admin keys (authorizeAdminKey, isAdminKey) and the SignatureVerifier keychain checks verifyKeychain and verifyKeychainAdmin.
Keychain V2 Signature Format ¶
Per Tempo spec, Keychain V2 signatures have format:
0x04 || root_account (20 bytes) || inner_signature (65 bytes)
Where:
- 0x04 is the Keychain V2 signature type identifier
- root_account is the account the access key signs on behalf of
- inner_signature is the secp256k1 signature from the access key (r || s || v)
The access key signs keccak256(0x04 || sig_hash || user_address) instead of the raw sig_hash. The 0x04 domain separator prevents cross-scheme signature confusion.
Total signature length: 86 bytes
Example Usage ¶
// Create a transaction
tx := transaction.NewTx()
tx.ChainID = big.NewInt(42431)
tx.Calls = []transaction.Call{{To: &recipient, Value: big.NewInt(1000000)}}
// Sign with access key instead of root key
accessKeySigner, _ := signer.NewSigner(accessKeyPrivateKey)
err := keychain.SignWithAccessKey(tx, accessKeySigner, rootAccount)
Call Scope Restrictions ¶
Access keys can be scoped to specific contracts, function selectors, and recipients using CallScope and SelectorRule. Use CallScopeBuilder to construct scopes:
token := common.HexToAddress("0x20c0000000000000000000000000000000000001")
scope := keychain.NewCallScopeBuilder(token).
Transfer([]common.Address{recipient}).
Approve(nil).
Build()
restrictions := keychain.NewKeyRestrictions(expiry).
WithAllowedCalls([]keychain.CallScope{scope})
call, _ := keychain.AuthorizeKey(keyID, keychain.SignatureTypeSecp256k1, restrictions)
AccountKeychain Precompile ¶
The precompile is located at address 0xAAAAAAAA00000000000000000000000000000000. It provides functions for:
- authorizeKey: Authorize a new access key with restrictions
- authorizeKey with witness: Authorize a new access key with a TIP-1053 witness
- authorizeAdminKey: Authorize a new admin key (T6, no restrictions)
- isAdminKey: Query whether a key is an admin key (T6)
- burnKeyAuthorizationWitness: Burn a TIP-1053 witness without authorizing a key
- isKeyAuthorizationWitnessBurned: Query burned witness state
- revokeKey: Revoke an access key
- updateSpendingLimit: Update spending limit for a token
- setAllowedCalls: Set or replace call scope restrictions for a key
- removeAllowedCalls: Remove call scope rules for a key+target pair
- getRemainingLimit: Query remaining spending limit
Tx-embedded Key Authorizations (TIP-1049) ¶
A root or admin key can authorize another key inside a transaction instead of a separate precompile call. Build a KeyAuthorization, sign it, and attach it to the transaction:
auth := keychain.NewKeyAuthorization(chainID, keychain.SignatureTypeSecp256k1, keyID). IntoAdmin(account) err := auth.SignAndAttach(tx, rootSigner)
Index ¶
- Constants
- Variables
- func BuildKeychainSignature(innerSig *signer.Signature, rootAccount common.Address) ([]byte, error)
- func DecodeAdminKeyAuthorized(topics []common.Hash) (account, keyID common.Address, err error)
- func EncodeGetRemainingLimitCalldata(accountAddress, keyID, tokenAddress common.Address) string
- func EncodeIsKeyAuthorizationWitnessBurnedCalldata(accountAddress common.Address, witness common.Hash) string
- func GetKeychainAddress() common.Address
- func GetSignatureVerifierAddress() common.Address
- func IsKeychainSignature(sig []byte) bool
- func ParseBoolResult(result []byte) (bool, error)
- func ParseKeychainSignature(sig []byte) (sigType byte, rootAccount common.Address, innerSig *signer.Signature, ...)
- func ParseRemainingLimitResult(result []byte) *big.Int
- func SignWithAccessKey(tx *transaction.Tx, accessKeySigner *signer.Signer, rootAccount common.Address) error
- func SignWithAccessKeyEnvelope(tx *transaction.Tx, accessKey signer.EnvelopeSigner, ...) error
- func ValidateAccessKeySignature(sig []byte) error
- func VerifyAccessKeySignature(tx *transaction.Tx) (accessKeyAddr, rootAccount common.Address, err error)
- type AuthorizedKey
- type Call
- func AuthorizeAdminKey(keyID common.Address, signatureType uint8, witness common.Hash) (Call, error)
- func AuthorizeKey(keyID common.Address, signatureType uint8, restrictions *KeyRestrictions) (Call, error)
- func AuthorizeKeyWithWitness(keyID common.Address, signatureType uint8, restrictions *KeyRestrictions, ...) (Call, error)
- func BurnKeyAuthorizationWitness(witness common.Hash) (Call, error)
- func IsAdminKey(account common.Address, keyID common.Address) (Call, error)
- func IsKeyAuthorizationWitnessBurned(account common.Address, witness common.Hash) (Call, error)
- func RemoveAllowedCalls(keyID common.Address, target common.Address) (Call, error)
- func RevokeKey(keyID common.Address) (Call, error)
- func SetAllowedCalls(keyID common.Address, scopes []CallScope) (Call, error)
- func UpdateSpendingLimit(keyID common.Address, token common.Address, newLimit *big.Int) (Call, error)
- func VerifyKeychain(account common.Address, digest common.Hash, signature []byte) (Call, error)
- func VerifyKeychainAdmin(account common.Address, digest common.Hash, signature []byte) (Call, error)
- type CallScope
- type CallScopeBuilder
- func (b *CallScopeBuilder) Approve(recipients []common.Address) *CallScopeBuilder
- func (b *CallScopeBuilder) Build() CallScope
- func (b *CallScopeBuilder) Transfer(recipients []common.Address) *CallScopeBuilder
- func (b *CallScopeBuilder) TransferWithMemo(recipients []common.Address) *CallScopeBuilder
- func (b *CallScopeBuilder) Unrestricted() *CallScopeBuilder
- func (b *CallScopeBuilder) WithSelector(selector [4]byte) *CallScopeBuilder
- type KeyAuthorization
- func (a *KeyAuthorization) BuildSigned(signature []byte) ([]interface{}, error)
- func (a *KeyAuthorization) IntoAdmin(account common.Address) *KeyAuthorization
- func (a *KeyAuthorization) Sign(s *signer.Signer) ([]interface{}, error)
- func (a *KeyAuthorization) SignAndAttach(tx *transaction.Tx, s *signer.Signer) error
- func (a *KeyAuthorization) SignWith(s signer.EnvelopeSigner) ([]interface{}, error)
- func (a *KeyAuthorization) SignatureHash() (common.Hash, error)
- func (a *KeyAuthorization) Validate() error
- func (a *KeyAuthorization) WithAccount(account common.Address) *KeyAuthorization
- func (a *KeyAuthorization) WithAllowedCalls(scopes []CallScope) *KeyAuthorization
- func (a *KeyAuthorization) WithExpiry(expiry uint64) *KeyAuthorization
- func (a *KeyAuthorization) WithLimits(limits []TokenLimit) *KeyAuthorization
- func (a *KeyAuthorization) WithNoCalls() *KeyAuthorization
- func (a *KeyAuthorization) WithNoSpending() *KeyAuthorization
- func (a *KeyAuthorization) WithWitness(witness common.Hash) *KeyAuthorization
- type KeyRestrictions
- func (kr *KeyRestrictions) AllowedCalls() []CallScope
- func (kr *KeyRestrictions) Expiry() uint64
- func (kr *KeyRestrictions) IsCallAllowed(target common.Address, input []byte) bool
- func (kr *KeyRestrictions) IsUnrestricted() bool
- func (kr *KeyRestrictions) Limits() []TokenLimit
- func (kr *KeyRestrictions) Validate() error
- func (kr *KeyRestrictions) WithAllowedCalls(scopes []CallScope) *KeyRestrictions
- func (kr *KeyRestrictions) WithEnforceLimits(enforce bool) *KeyRestrictions
- func (kr *KeyRestrictions) WithLimits(limits []TokenLimit) *KeyRestrictions
- func (kr *KeyRestrictions) WithNoCalls() *KeyRestrictions
- type SelectorRule
- type SpendingLimit
- type TokenLimit
Constants ¶
const ( SignatureTypeSecp256k1 = 0 SignatureTypeP256 = 1 SignatureTypeWebAuthn = 2 )
SignatureType constants matching the Rust/Solidity enum.
const ( // KeychainSignatureType is the Keychain V2 signature type identifier. KeychainSignatureType = 0x04 // InnerSignatureLength is the length of the inner secp256k1 signature (r + s + v). InnerSignatureLength = 65 // KeychainSignatureLength is the total length of a Keychain signature. // Format: type (1) + root_account (20) + inner_signature (65) = 86 bytes. KeychainSignatureLength = 86 // AccountKeychainAddress is the address of the AccountKeychain precompile. AccountKeychainAddress = "0xAAAAAAAA00000000000000000000000000000000" )
const AdminKeyAuthorizedTopic = "0x493bc0240c1da6c792754dc5247d39ed76c71c99a43e16777538687f8d05e88e"
AdminKeyAuthorizedTopic is the topic0 hash for the T6 AdminKeyAuthorized(address,address) event emitted by AccountKeychain when an admin key is authorized.
const AuthorizeAdminKeySelector = "0x9a424307"
AuthorizeAdminKeySelector is the function selector for the T6 authorizeAdminKey(address,uint8,bytes32) call.
const AuthorizeKeySelector = "0x54063a55"
AuthorizeKeySelector is the function selector for the legacy (pre-T3) authorizeKey(address,uint8,uint64,bool,(address,uint256)[]).
const AuthorizeKeyT3Selector = "0x980a6025"
AuthorizeKeyT3Selector is the function selector for the T3+ authorizeKey(address,uint8,(uint64,bool,(address,uint256,uint64)[],bool,(address,(bytes4,address[])[])[]))
const AuthorizeKeyWithWitnessSelector = "0xe3c154d2"
AuthorizeKeyWithWitnessSelector is the function selector for the T5 authorizeKey(address,uint8,KeyRestrictions,bytes32) overload.
const BurnKeyAuthorizationWitnessSelector = "0xcff31c46"
BurnKeyAuthorizationWitnessSelector is the function selector for burnKeyAuthorizationWitness(bytes32).
const GetKeySelector = "0xbc298553"
GetKeySelector is the function selector for getKey(address,address).
const GetRemainingLimitSelector = "0x63b4290d"
GetRemainingLimitSelector is the function selector for getRemainingLimit(address,address,address).
const GetTransactionKeySelector = "0xb07fbc1a"
GetTransactionKeySelector is the function selector for getTransactionKey().
const IsAdminKeySelector = "0x9009a18d"
IsAdminKeySelector is the function selector for isAdminKey(address,address).
const IsKeyAuthorizationWitnessBurnedSelector = "0x8e6c7e11"
IsKeyAuthorizationWitnessBurnedSelector is the function selector for isKeyAuthorizationWitnessBurned(address,bytes32).
const RemoveAllowedCallsSelector = "0xf3941811"
RemoveAllowedCallsSelector is the function selector for removeAllowedCalls(address,address).
const RevokeKeySelector = "0x5ae7ab32"
RevokeKeySelector is the function selector for revokeKey(address).
const SetAllowedCallsSelector = "0xf5456703"
SetAllowedCallsSelector is the function selector for setAllowedCalls(address,(address,(bytes4,address[])[])[]).
const SignatureVerifierAddress = "0x5165300000000000000000000000000000000000"
SignatureVerifierAddress is the address of the TIP-1020 SignatureVerifier precompile.
const UpdateSpendingLimitSelector = "0xcbbb4480"
UpdateSpendingLimitSelector is the function selector for updateSpendingLimit(address,address,uint256).
const VerifyKeychainAdminSelector = "0x5f6fc5b7"
VerifyKeychainAdminSelector is the function selector for the T6 verifyKeychainAdmin(address,bytes32,bytes) call.
const VerifyKeychainSelector = "0x6c0c731e"
VerifyKeychainSelector is the function selector for the T6 verifyKeychain(address,bytes32,bytes) call.
Variables ¶
var ( SelectorTransfer = [4]byte{0xa9, 0x05, 0x9c, 0xbb} // cast sig "transfer(address,uint256)" = 0xa9059cbb SelectorApprove = [4]byte{0x09, 0x5e, 0xa7, 0xb3} // cast sig "approve(address,uint256)" = 0x095ea7b3 SelectorTransferWithMemo = [4]byte{0x95, 0x77, 0x7d, 0x59} // cast sig "transferWithMemo(address,uint256,bytes32)" = 0x95777d59 SelectorWildcard = [4]byte{0x00, 0x00, 0x00, 0x00} )
TIP20 function selectors.
Functions ¶
func BuildKeychainSignature ¶
BuildKeychainSignature creates a Keychain V2 signature from an inner secp256k1 signature.
The Keychain V2 signature format is:
0x04 || root_account (20 bytes) || inner_signature (65 bytes)
The inner signature is r || s || v with v = 27/28. innerSig.YParity may be 0/1 or 27/28.
Parameters:
- innerSig: The secp256k1 signature from the access key
- rootAccount: The address of the root account (the account the access key acts on behalf of)
Returns the 86-byte Keychain signature, or an error if innerSig is malformed.
func DecodeAdminKeyAuthorized ¶ added in v0.5.0
DecodeAdminKeyAuthorized decodes an AdminKeyAuthorized log.
Both account and keyID are indexed: topics[0] is the event signature, topics[1] is account, topics[2] is keyID. keyID is the address-derived key ID (the Solidity event names it publicKey).
func EncodeGetRemainingLimitCalldata ¶
EncodeGetRemainingLimitCalldata encodes the calldata for getRemainingLimit(address,address,address).
Parameters:
- accountAddress: The root wallet address
- keyID: The access key ID (address)
- tokenAddress: The token to check limit for
Returns the hex-encoded calldata (with 0x prefix).
func EncodeIsKeyAuthorizationWitnessBurnedCalldata ¶ added in v0.5.0
func EncodeIsKeyAuthorizationWitnessBurnedCalldata(accountAddress common.Address, witness common.Hash) string
EncodeIsKeyAuthorizationWitnessBurnedCalldata encodes the calldata for isKeyAuthorizationWitnessBurned(address,bytes32).
Parameters:
- accountAddress: The account address
- witness: The TIP-1053 key authorization witness
Returns the hex-encoded calldata (with 0x prefix).
func GetKeychainAddress ¶
GetKeychainAddress returns the AccountKeychain precompile address.
func GetSignatureVerifierAddress ¶ added in v0.5.0
GetSignatureVerifierAddress returns the SignatureVerifier precompile address.
func IsKeychainSignature ¶
IsKeychainSignature checks if the given signature bytes are a Keychain V2 signature: 0x04 || root account || a secp256k1, P256 or WebAuthn signature.
func ParseBoolResult ¶ added in v0.5.0
ParseBoolResult parses a 32-byte ABI-encoded bool return value.
The result must be exactly 32 bytes, with zero padding and a canonical value byte (0x00 or 0x01); anything else returns an error. This is strict because the result gates authorization checks.
func ParseKeychainSignature ¶
func ParseKeychainSignature(sig []byte) (sigType byte, rootAccount common.Address, innerSig *signer.Signature, err error)
ParseKeychainSignature parses a Keychain signature into its components.
Returns the signature type, root account address, and inner signature, whose YParity is 0 or 1. The inner recovery id byte may be 27/28 or 0/1. Returns an error if the signature is invalid.
func ParseRemainingLimitResult ¶
ParseRemainingLimitResult parses the result of a getRemainingLimit call.
The result is a 32-byte big-endian uint256.
func SignWithAccessKey ¶
func SignWithAccessKey(tx *transaction.Tx, accessKeySigner *signer.Signer, rootAccount common.Address) error
SignWithAccessKey signs a Tempo transaction using an access key.
This creates a Keychain V2 signature that allows the access key to sign transactions on behalf of the root account.
The access key signs keccak256(0x04 || sig_hash || user_address) instead of the raw sig_hash, providing domain separation.
The function:
- Sets tx.From to the root account address
- Computes the signing hash
- Signs keccak256(0x04 || sig_hash || root_account) with the access key
- Wraps the signature in Keychain format (0x04 || root || inner_sig)
Parameters:
- tx: The transaction to sign (will be modified in place)
- accessKeySigner: The signer for the access key
- rootAccount: The address of the root account
Returns an error if signing fails.
func SignWithAccessKeyEnvelope ¶ added in v0.7.0
func SignWithAccessKeyEnvelope(tx *transaction.Tx, accessKey signer.EnvelopeSigner, rootAccount common.Address) error
SignWithAccessKeyEnvelope signs a Tempo transaction for rootAccount with an access key of any type (secp256k1, P256 or WebAuthn), as a Keychain V2 envelope: 0x04 || rootAccount || inner, the inner signature over keccak256(0x04 || sig_hash || rootAccount), as viem's access-key accounts sign.
func ValidateAccessKeySignature ¶
ValidateAccessKeySignature is a helper that validates a signature is a proper keychain signature.
It accepts a Keychain V2 envelope with any primitive inner signature (86 bytes for secp256k1, longer for P256 and WebAuthn) and checks the layout only.
func VerifyAccessKeySignature ¶
func VerifyAccessKeySignature(tx *transaction.Tx) (accessKeyAddr, rootAccount common.Address, err error)
VerifyAccessKeySignature verifies a Keychain V2 signature (with a secp256k1, P256 or WebAuthn access key) and returns the access key address and the root account it signed for. Legacy V1 envelopes are rejected: their inner signature does not commit to the account; transaction.RecoverSigner reports them. Whether the root account authorized the key is on-chain state the caller must check.
Types ¶
type AuthorizedKey ¶
type AuthorizedKey struct {
KeyID common.Address
SignatureType uint8 // 0 = Secp256k1, 1 = P256, 2 = WebAuthn
Expiry uint64
EnforceLimits bool
IsRevoked bool
}
AuthorizedKey represents an authorized access key with its configuration.
type Call ¶ added in v0.4.0
Call represents an EVM call with target address and calldata.
func AuthorizeAdminKey ¶ added in v0.5.0
func AuthorizeAdminKey(keyID common.Address, signatureType uint8, witness common.Hash) (Call, error)
AuthorizeAdminKey builds an authorizeAdminKey(address,uint8,bytes32) call.
Admin keys can manage other keys but carry no spending limits, call scopes, or expiry. A zero witness (bytes32(0)) is valid unless it has already been burned for the caller's account.
func AuthorizeKey ¶ added in v0.4.0
func AuthorizeKey(keyID common.Address, signatureType uint8, restrictions *KeyRestrictions) (Call, error)
AuthorizeKey builds an authorizeKey(address,uint8,KeyRestrictions) call.
func AuthorizeKeyWithWitness ¶ added in v0.5.0
func AuthorizeKeyWithWitness(keyID common.Address, signatureType uint8, restrictions *KeyRestrictions, witness common.Hash) (Call, error)
AuthorizeKeyWithWitness builds an authorizeKey(address,uint8,KeyRestrictions,bytes32) call.
func BurnKeyAuthorizationWitness ¶ added in v0.5.0
BurnKeyAuthorizationWitness builds a burnKeyAuthorizationWitness(bytes32) call.
func IsAdminKey ¶ added in v0.5.0
IsAdminKey builds an isAdminKey(address,address) call.
The call returns true when keyID is an active admin key on account, or when keyID == account (the root key is implicitly admin). Parse the result with ParseBoolResult.
func IsKeyAuthorizationWitnessBurned ¶ added in v0.5.0
IsKeyAuthorizationWitnessBurned builds an isKeyAuthorizationWitnessBurned(address,bytes32) call.
func RemoveAllowedCalls ¶ added in v0.4.0
RemoveAllowedCalls builds a removeAllowedCalls(address,address) call.
func SetAllowedCalls ¶ added in v0.4.0
SetAllowedCalls builds a setAllowedCalls(address,CallScope[]) call.
func UpdateSpendingLimit ¶ added in v0.4.0
func UpdateSpendingLimit(keyID common.Address, token common.Address, newLimit *big.Int) (Call, error)
UpdateSpendingLimit builds an updateSpendingLimit(address,address,uint256) call.
func VerifyKeychain ¶ added in v0.5.0
VerifyKeychain builds a verifyKeychain(address,bytes32,bytes) call.
It returns true when signature over digest came from an active access key on account. Only V2 keychain signatures are accepted. The envelope embeds an account that is checked against account, so cross-account replay is prevented; digest should still be domain-separated (chain ID, contract, purpose) against other-context replay.
The precompile reverts on invalid/legacy/non-keychain signatures, so a false result means a valid signature that failed the account/key check. Callers must handle the eth_call error path, not just ParseBoolResult.
func VerifyKeychainAdmin ¶ added in v0.5.0
func VerifyKeychainAdmin(account common.Address, digest common.Hash, signature []byte) (Call, error)
VerifyKeychainAdmin builds a verifyKeychainAdmin(address,bytes32,bytes) call.
It returns true when signature over digest came from the root key or an active admin access key on account. Only V2 keychain signatures are accepted. The envelope embeds an account that is checked against account, so cross-account replay is prevented; digest should still be domain-separated (chain ID, contract, purpose) against other-context replay.
The precompile reverts on invalid/legacy/non-keychain signatures, so a false result means a valid signature that failed the account/key check. Callers must handle the eth_call error path, not just ParseBoolResult.
type CallScope ¶ added in v0.4.0
type CallScope struct {
Target common.Address
SelectorRules []SelectorRule
}
CallScope restricts the calls an access key may make to a single target contract, optionally scoped to specific function selectors and recipients.
type CallScopeBuilder ¶ added in v0.4.0
type CallScopeBuilder struct {
// contains filtered or unexported fields
}
CallScopeBuilder builds a CallScope with a fluent API.
func NewCallScopeBuilder ¶ added in v0.4.0
func NewCallScopeBuilder(target common.Address) *CallScopeBuilder
NewCallScopeBuilder creates a builder for the given target contract.
func (*CallScopeBuilder) Approve ¶ added in v0.4.0
func (b *CallScopeBuilder) Approve(recipients []common.Address) *CallScopeBuilder
Approve allows approve(address,uint256) calls, optionally restricted to the given spender addresses.
func (*CallScopeBuilder) Build ¶ added in v0.4.0
func (b *CallScopeBuilder) Build() CallScope
Build returns the constructed CallScope.
func (*CallScopeBuilder) Transfer ¶ added in v0.4.0
func (b *CallScopeBuilder) Transfer(recipients []common.Address) *CallScopeBuilder
Transfer allows transfer(address,uint256) calls, optionally restricted to the given recipients.
func (*CallScopeBuilder) TransferWithMemo ¶ added in v0.4.0
func (b *CallScopeBuilder) TransferWithMemo(recipients []common.Address) *CallScopeBuilder
TransferWithMemo allows transferWithMemo(address,uint256,bytes32) calls, optionally restricted to the given recipients.
func (*CallScopeBuilder) Unrestricted ¶ added in v0.4.0
func (b *CallScopeBuilder) Unrestricted() *CallScopeBuilder
Unrestricted allows any call to the target (wildcard selector, no recipient filtering).
func (*CallScopeBuilder) WithSelector ¶ added in v0.4.0
func (b *CallScopeBuilder) WithSelector(selector [4]byte) *CallScopeBuilder
WithSelector allows calls matching an arbitrary 4-byte function selector.
type KeyAuthorization ¶ added in v0.5.0
type KeyAuthorization struct {
ChainID uint64
KeyType uint8
KeyID common.Address
Expiry uint64
Limits *[]TokenLimit
AllowedCalls *[]CallScope
Witness *common.Hash
IsAdmin bool
Account *common.Address
}
KeyAuthorization is a tx-embedded key authorization (TIP-1049). It lets a root or admin key authorize another key inside a transaction, rather than via a separate AccountKeychain precompile call.
Optional fields use nil/zero to mean "absent":
- Expiry == 0 means the key never expires.
- Limits == nil means unlimited spending; a non-nil empty slice means no spending.
- AllowedCalls == nil means unrestricted calls; a non-nil empty slice means deny all.
- Witness == nil means no witness; a non-nil value (including zero) attaches one.
- Account == nil means the field is omitted.
func DecodeKeyAuthorization ¶ added in v0.7.0
func DecodeKeyAuthorization(signed []interface{}) (*KeyAuthorization, []byte, error)
DecodeKeyAuthorization decodes a signed key authorization as it appears in a transaction (transaction.Tx.KeyAuthorization after transaction.Deserialize) or as Sign and BuildSigned return it: [authorization, signature]. It is the inverse of BuildSigned.
The returned signature is the root or admin key's primitive signature: for secp256k1, 65 bytes r || s || v with v normalized to 27/28 (0/1 is accepted, as the node accepts it); for P256 and WebAuthn, the raw bytes with their type prefix.
Decoding follows tempo-primitives: integers must be minimally encoded, addresses must be 20 bytes, and an absent optional field may be written as an empty placeholder (0x80) only when a later field is present. Semantic rules such as "admin keys cannot have limits" are not enforced here; call Validate on the result for those.
func NewKeyAuthorization ¶ added in v0.5.0
func NewKeyAuthorization(chainID uint64, keyType uint8, keyID common.Address) *KeyAuthorization
NewKeyAuthorization creates an unrestricted key authorization (no expiry, limits, or call scopes).
func NewKeyAuthorizationFor ¶ added in v0.7.0
func NewKeyAuthorizationFor(chainID uint64, accessKey signer.EnvelopeSigner) *KeyAuthorization
NewKeyAuthorizationFor authorizes accessKey on chainID: its key type and address (for P256 and WebAuthn keys, the address of the public key).
func (*KeyAuthorization) BuildSigned ¶ added in v0.5.0
func (a *KeyAuthorization) BuildSigned(signature []byte) ([]interface{}, error)
BuildSigned wraps the authorization with a pre-computed primitive signature.
Use this for P256 or WebAuthn signatures, where signature is the raw primitive signature bytes (with their type prefix). For secp256k1, pass 65 raw bytes (r || s || v) or use Sign.
func (*KeyAuthorization) IntoAdmin ¶ added in v0.5.0
func (a *KeyAuthorization) IntoAdmin(account common.Address) *KeyAuthorization
IntoAdmin makes this an admin-key authorization bound to account. Admin keys carry no expiry, limits, or call scopes.
func (*KeyAuthorization) Sign ¶ added in v0.5.0
func (a *KeyAuthorization) Sign(s *signer.Signer) ([]interface{}, error)
Sign signs the authorization with a secp256k1 key and returns the signed key authorization value to assign to tx.KeyAuthorization.
func (*KeyAuthorization) SignAndAttach ¶ added in v0.5.0
func (a *KeyAuthorization) SignAndAttach(tx *transaction.Tx, s *signer.Signer) error
SignAndAttach signs the authorization with a secp256k1 key and attaches it to the transaction.
Attach the authorization BEFORE signing the transaction: the key authorization is part of the transaction's signing payload, so attaching it after signing would invalidate the sender (and fee payer) signature. This returns an error if the transaction is already signed.
For admin-signed authorizations, set Account (via IntoAdmin or WithAccount). For same-tx authorize-and-use, attach first, then sign the carrying transaction with the newly authorized key.
func (*KeyAuthorization) SignWith ¶ added in v0.7.0
func (a *KeyAuthorization) SignWith(s signer.EnvelopeSigner) ([]interface{}, error)
SignWith signs the authorization with a root (or admin) key of any type and returns the signed key authorization value to assign to tx.KeyAuthorization.
func (*KeyAuthorization) SignatureHash ¶ added in v0.5.0
func (a *KeyAuthorization) SignatureHash() (common.Hash, error)
SignatureHash returns keccak256(rlp(authorization)), the hash the root or admin key signs.
func (*KeyAuthorization) Validate ¶ added in v0.5.0
func (a *KeyAuthorization) Validate() error
Validate checks for conflicting settings.
func (*KeyAuthorization) WithAccount ¶ added in v0.5.0
func (a *KeyAuthorization) WithAccount(account common.Address) *KeyAuthorization
WithAccount binds this authorization to a target account without making the key an admin key.
func (*KeyAuthorization) WithAllowedCalls ¶ added in v0.5.0
func (a *KeyAuthorization) WithAllowedCalls(scopes []CallScope) *KeyAuthorization
WithAllowedCalls sets call-scope restrictions.
func (*KeyAuthorization) WithExpiry ¶ added in v0.5.0
func (a *KeyAuthorization) WithExpiry(expiry uint64) *KeyAuthorization
WithExpiry sets an expiry timestamp. Zero means the key never expires.
func (*KeyAuthorization) WithLimits ¶ added in v0.5.0
func (a *KeyAuthorization) WithLimits(limits []TokenLimit) *KeyAuthorization
WithLimits sets token spending limits.
func (*KeyAuthorization) WithNoCalls ¶ added in v0.5.0
func (a *KeyAuthorization) WithNoCalls() *KeyAuthorization
WithNoCalls denies all calls (scoped mode with an empty allowlist).
func (*KeyAuthorization) WithNoSpending ¶ added in v0.5.0
func (a *KeyAuthorization) WithNoSpending() *KeyAuthorization
WithNoSpending denies all spending (limits enforced with an empty allowlist).
func (*KeyAuthorization) WithWitness ¶ added in v0.5.0
func (a *KeyAuthorization) WithWitness(witness common.Hash) *KeyAuthorization
WithWitness attaches a TIP-1053 witness (zero is a valid value).
type KeyRestrictions ¶ added in v0.4.0
type KeyRestrictions struct {
// contains filtered or unexported fields
}
KeyRestrictions holds all the restrictions for an access key.
func NewKeyRestrictions ¶ added in v0.4.0
func NewKeyRestrictions(expiry uint64) *KeyRestrictions
NewKeyRestrictions creates an unrestricted KeyRestrictions with the given expiry. Calls are unrestricted by default (allowAnyCalls=true).
func (*KeyRestrictions) AllowedCalls ¶ added in v0.4.0
func (kr *KeyRestrictions) AllowedCalls() []CallScope
AllowedCalls returns the call scope allowlist.
func (*KeyRestrictions) Expiry ¶ added in v0.4.0
func (kr *KeyRestrictions) Expiry() uint64
Expiry returns the expiry timestamp.
func (*KeyRestrictions) IsCallAllowed ¶ added in v0.4.0
func (kr *KeyRestrictions) IsCallAllowed(target common.Address, input []byte) bool
IsCallAllowed checks whether a call to target with the given input data is permitted by these restrictions.
func (*KeyRestrictions) IsUnrestricted ¶ added in v0.4.0
func (kr *KeyRestrictions) IsUnrestricted() bool
IsUnrestricted returns true if calls are unrestricted.
func (*KeyRestrictions) Limits ¶ added in v0.4.0
func (kr *KeyRestrictions) Limits() []TokenLimit
Limits returns the token spending limits.
func (*KeyRestrictions) Validate ¶ added in v0.4.0
func (kr *KeyRestrictions) Validate() error
Validate checks for conflicting settings.
func (*KeyRestrictions) WithAllowedCalls ¶ added in v0.4.0
func (kr *KeyRestrictions) WithAllowedCalls(scopes []CallScope) *KeyRestrictions
WithAllowedCalls sets the call-scope allowlist and disables allowAnyCalls.
func (*KeyRestrictions) WithEnforceLimits ¶ added in v0.4.0
func (kr *KeyRestrictions) WithEnforceLimits(enforce bool) *KeyRestrictions
WithEnforceLimits sets the enforceLimits flag.
func (*KeyRestrictions) WithLimits ¶ added in v0.4.0
func (kr *KeyRestrictions) WithLimits(limits []TokenLimit) *KeyRestrictions
WithLimits sets the token spending limits.
func (*KeyRestrictions) WithNoCalls ¶ added in v0.4.0
func (kr *KeyRestrictions) WithNoCalls() *KeyRestrictions
WithNoCalls sets an empty call-scope allowlist (deny all calls).
type SelectorRule ¶ added in v0.4.0
SelectorRule restricts a single function selector to an optional set of first-argument (recipient) addresses. An empty Recipients list means any recipient is allowed.
type SpendingLimit ¶
SpendingLimit represents a per-token spending limit for an access key.