> For the complete documentation index, see [llms.txt](https://docs.t-rex.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.t-rex.network/reference/identity-suite/identityfactory.md).

# IdentityFactory

`IdentityFactory` creates every ONCHAINID and is the global identity registry of a network: it records the type of each identity and which wallet is linked to which identity, on any chain. The `TREXRegistry` of every asset reads it. The concepts are in [Identity types and factory gating](/identity-onchainid/identity-types-and-factory-gating.md) and [Wallet linking and the global identity registry](/identity-onchainid/wallet-linking-and-the-global-identity-registry.md).

### At a glance

|                    |                                                                                                             |
| ------------------ | ----------------------------------------------------------------------------------------------------------- |
| **Source**         | `contracts/factory/IdentityFactory.sol`                                                                     |
| **Interface**      | `IIdentityFactory`, ERC-7786 recipient                                                                      |
| **Deployed as**    | One contract per network, not upgradeable. It owns the beacon of the identities, at the address `beacon()`  |
| **Signing domain** | ERC-712 name `IdentityFactory`, version `1`                                                                 |
| **Access**         | Settings are restricted by the access manager of the network. Linking and revoking are called by identities |

### Create an identity

| Function                                                   | Access                                                 | Behavior                                                                                                                     |
| ---------------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `createIdentity(_identityType, _salt, _keys)`              | Anyone, for a type whose policy allows self-deployment | Deploys an identity for the caller, links the caller as its first wallet, and returns its address                            |
| `createIdentityFor(_account, _identityType, _salt, _keys)` | A holder of the role set for the type                  | Deploys an identity for `_account` and links `_account` to it. For a type bound to one contract, `_account` is that contract |

Both record the type of the identity, which never changes, and emit `IdentityDeployed`, `IdentityTypeRecorded` and `AccountLinked`.

| Reverts with                                                                                                         | Condition                                                                                                  |
| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `BeaconNotInitialized`                                                                                               | The beacon is not deployed                                                                                 |
| `UnknownIdentityType`                                                                                                | The type has no policy                                                                                     |
| `IdentityTypeNotSelfDeployable`                                                                                      | `createIdentity` for a type that is not self-deployable                                                    |
| `NotAuthorizedForIdentityType`, `DelayedRoleNotSupported`                                                            | `createIdentityFor` by a caller without the role of the type, or with a delayed role                       |
| `EmptyString`, `EmptyListOfKeys`, `NoManagementKeyInKeys`                                                            | An empty salt, no key, no `MANAGEMENT` key                                                                 |
| `CallerKeyCannotBeModule`                                                                                            | A key of type `MODULE` is supplied                                                                         |
| `KeyNotForAccount`, `AccountNotSoleManagementKey`                                                                    | `createIdentityFor`: a key that is not a key of `_account`, or `_account` is not the only `MANAGEMENT` key |
| `WalletAlreadyLinkedToIdentity`, `WalletBoundToAnotherIdentity`, `WalletAlreadyRevoked`, `CannotLinkFactoryIdentity` | The first wallet cannot be linked                                                                          |

A `KeyParam` is `(bytes32 keyHash, uint256 purpose, uint256 keyType, bytes signerData, bytes clientData)`. Guide: [02 Deploy an ONCHAINID](/guides/identity/02.-deploy-an-onchainid.md).

### Link and revoke wallets

| Function                                         | Access                                   | Reverts with                                                                                                                                                                                                                                                                                                                  |
| ------------------------------------------------ | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `linkAccount(account, signature, nonce, expiry)` | The identity, for a wallet of this chain | `NotFactoryIdentity`, `CannotLinkToAssetIdentity`, `CannotLinkFactoryIdentity`, `NonCanonicalAccount`, `NonEvmAccount`, `AccountNotOnLocalChain`, `ExpiredSignature`, `UntrustedVerifier`, `InvalidSignature`, `WalletAlreadyLinkedToIdentity`, `WalletBoundToAnotherIdentity`, `WalletAlreadyRevoked`. Emits `AccountLinked` |
| `revokeAccount(account)`                         | The identity                             | `NonCanonicalAccount`, `WalletNotLinkedToIdentity`, `WalletNotActive`, `CannotRevokeFromNonSigningIdentity`. Emits `AccountRevoked`                                                                                                                                                                                           |
| `settlePendingCrossChainLink(account, accept)`   | The identity named in the proposal       | `PendingCrossChainLinkIdentityMismatch`, `PendingCrossChainLinkExpired`, and the linking errors. Emits `AccountLinked` and `CrossChainLinkConfirmed`, or `CrossChainLinkRejected`                                                                                                                                             |
| `receiveMessage(receiveId, sender, payload)`     | A gateway trusted for the origin chain   | `CrossChainSenderWalletMismatch`, `CrossChainLinkForLocalWallet`, `WalletAlreadyHasEntry`, `PendingCrossChainLinkExpired`. Emits `PendingCrossChainLinkProposed`                                                                                                                                                              |

* **A wallet proves control.** A wallet of this chain signs the ERC-712 message `LinkAccount(bytes account,address identity,uint256 nonce,uint256 expiry)` in the domain of the factory, with the nonce `nonceForAccount(account)`. A wallet of another chain sends a proposal from its own chain, with the payload `abi.encode(wallet, identity, expiry)`, and the identity accepts or declines it.
* **The identity calls the factory.** The factory is a management target of an identity, so these calls need a `MANAGEMENT` key.
* **A link is for one identity, and a revocation is final.** A wallet linked to an identity cannot be linked to another, and a revoked wallet cannot be linked again.
* **Some identities take no extra wallet.** An `ASSET` identity is bound to its token, and an identity of a type bound to one contract cannot revoke that contract.

Guides: [07 Link a wallet to an ONCHAINID](/guides/identity/07.-link-a-wallet-to-an-onchainid.md), [23 Revoke a wallet](/guides/identity/23.-revoke-a-wallet.md).

### Reads

| View                                                                                  | Returns                                                                                                                              |
| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `getIdentity(account)`                                                                | The identity a wallet is actively linked to, or zero                                                                                 |
| `getIdentityIncludingRevoked(account)`                                                | The identity and the status of the link: `None`, `Active` or `Revoked`. The address of an identity resolves to itself, with `Active` |
| `getAccountStatus(account)`                                                           | The status alone                                                                                                                     |
| `getIdentityWithType(account)`                                                        | The identity and its type                                                                                                            |
| `getAccounts(identity, start, end)`, `getAccountsCount(identity)`                     | The wallets actively linked to an identity                                                                                           |
| `isFactoryIdentity(identity)`, `identityTypeOf(identity)`                             | Whether the factory deployed the identity, and its type. 0 for an address the factory did not deploy                                 |
| `nonceForAccount(account)`                                                            | The nonce a link signature must carry                                                                                                |
| `getPendingCrossChainLink(account)`                                                   | The identity and the expiry of a pending proposal                                                                                    |
| `getIdentityTypePolicy(_identityType)`                                                | `roleId`, `selfDeployable`, `singleBinding`, `registered`                                                                            |
| `getIdentityTypeModules(_identityType)`                                               | The modules an identity of the type is created with                                                                                  |
| `isTrustedGateway(gateway, chainType, chainReference)`, `isTrustedVerifier(verifier)` | The two lists of the factory                                                                                                         |
| `beacon()`                                                                            | The beacon of the identities                                                                                                         |

The reads that take a wallet revert with `NonCanonicalAccount` for an address that is not in canonical form.

### Settings

| Function                                                                         | Access             | Reverts with                                                                                                                                                                                      |
| -------------------------------------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setIdentityTypePolicy(_identityType, _roleId, _selfDeployable, _singleBinding)` | Network governance | `ZeroIdentityType`, `SingleBindingTypeCannotBePublic`. Emits `IdentityTypePolicySet`                                                                                                              |
| `removeIdentityTypePolicy(_identityType)`                                        | Network governance | Emits `IdentityTypePolicyRemoved`                                                                                                                                                                 |
| `setIdentityTypeModules(_identityType, _modules)`                                | Network governance | Emits `IdentityTypeModulesSet`. Applies to identities created afterwards                                                                                                                          |
| `setTrustedGateway(gateway, chainType, chainReference, trusted)`                 | Network governance | `ZeroAddress`. Emits `TrustedGatewaySet`. This list is separate from the `TrustedGatewayRegistry` of the token suite                                                                              |
| `setTrustedVerifier(verifier, trusted)`                                          | Network governance | `ZeroAddress`. Emits `TrustedVerifierSet`                                                                                                                                                         |
| `initializeBeacon(implementation)`                                               | Network governance | `BeaconAlreadyInitialized`, `ImplementationNotAContract`, `ImplementationFactoryMismatch`, `ImplementationInitializersNotDisabled`, `BeaconAddressMismatch`. Emits `BeaconInitialized`            |
| `upgradeBeacon(newImplementation, expectedVersion)`                              | Network governance | `ImplementationNotAContract`, `ImplementationFactoryMismatch`, `ImplementationRegistryMismatch`, `ImplementationInitializersNotDisabled`, `ImplementationVersionMismatch`. Emits `BeaconUpgraded` |

A `ModuleInstall` is `(uint256 moduleType, address module, bytes initData, uint256 purpose)`.

> **Trust statement.** `upgradeBeacon` changes the code of every identity of the network in one transaction. The factory accepts only an implementation that names this factory and the same key registry, and whose initializers are locked.

### Events

| Event                                                                                                                                                                                                            | Emitted when                              |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| `IdentityDeployed(address indexed identity, bytes account, uint256 indexed identityType, address indexed deployer)`                                                                                              | An identity is created                    |
| `IdentityTypeRecorded(address indexed identity, uint256 identityType)`                                                                                                                                           | Same transaction: its type, recorded once |
| `AccountLinked(bytes account, address indexed identity, address caller)`, `AccountRevoked` (same arguments)                                                                                                      | A wallet is linked, revoked               |
| `PendingCrossChainLinkProposed(bytes account, address indexed identity, uint256 expiry, address gateway, bytes32 receiveId)`                                                                                     | A wallet of another chain asks for a link |
| `CrossChainLinkConfirmed(bytes account, address indexed identity)`, `CrossChainLinkRejected(bytes account, address indexed identity, uint256 expiry)`                                                            | The identity accepts, declines            |
| `IdentityTypePolicySet(uint256 indexed identityType, uint64 indexed roleId, bool selfDeployable, bool singleBinding, address caller)`, `IdentityTypePolicyRemoved(uint256 indexed identityType, address caller)` | The policy of a type is set, removed      |
| `IdentityTypeModulesSet(uint256 indexed identityType, Structs.ModuleInstall[] modules, address caller)`                                                                                                          | The modules of a type are set             |
| `TrustedGatewaySet(address indexed gateway, bytes2 chainType, bytes chainReference, bool trusted, address caller)`, `TrustedVerifierSet(address indexed verifier, bool trusted, address caller)`                 | A list of the factory changes             |
| `BeaconInitialized(address indexed implementation, address caller)`, `BeaconUpgraded(address indexed implementation, string version, address caller)`                                                            | The beacon is deployed, upgraded          |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.t-rex.network/reference/identity-suite/identityfactory.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
