access-control.role-granted.provisional
A role was granted on the access-control manager; the grant is provisional until the indexer reaches the configured reorg depth.
Delivery contract
| Field | Value |
|---|---|
| Event type | access-control.role-granted.provisional |
| Version | 2 |
| Lifecycle state | provisional |
| Counter-signed receipts | No event-specific advice |
| SDK type | Webhook.AccessControlRoleGrantedProvisionalV2 |
The receipt recommendation does not change delivery behavior. DALP waits for a counter-signed receipt only if the webhook endpoint's counterSignedReceipts value is true when DALP queues the delivery. When the value is false, a normal 2xx response completes the delivery.
Related references:
None.
When to consume this event
Consume access-control.role-granted.provisional when your integration needs early notice that an account received a role on an access-control manager.
Use the event to stage permission-aware synchronization, administrative review queues, or audit exports that can tolerate provisional indexing. Do not treat the role membership as final while the observation is still inside the configured reorg depth.
Your consumer must handle a later retraction for the same on-chain observation. Store evt_id, request.idempotency_key when present, roleId, accountAddress, accessManagerAddress, chainId, and transactionHash. These values keep retries or replayed deliveries from creating duplicate permission changes downstream.
The payload carries the access manager, grantee account, role identifier and field name, log actor, configured immediate admin role, owning system, chain ID, block number, and transaction hash. accessManagerAddress scopes the role. actorAddress is the sender recorded in the role log; the log does not prove which role in the admin hierarchy authorized the actor. A missing role-admin override reports the contract's default admin role. An unreadable stored override reports adminRoleId: null. Treat accountAddress and actorAddress as personal-data-bearing fields for webhook privacy reviews. If your endpoint is configured for thin payload delivery, do not depend on those fields in the first delivery.
roleId is the raw on-chain role identifier. roleFieldName and adminRoleFieldName name known roles such as admin, systemManager, identityManager, tokenManager, and complianceManager; an unknown role has a null field name.
See webhook idempotency and on-chain outcome for retry, replay, payload-shape, and provisional-event handling.
Payload schema
The schema and examples describe the full payload. Thin delivery omits personal data fields. Use the payload-shape guidance to choose the endpoint configuration.
{
"type": "object",
"properties": {
"accessManagerAddress": {
"type": "string",
"minLength": 42,
"maxLength": 42,
"pattern": "^0x[a-fA-F0-9]{40}$",
"description": "A valid Ethereum address (42 characters, starting with 0x)",
"examples": ["0x71C7656EC7ab88b098defB751B7401B5f6d8976F"]
},
"accountAddress": {
"type": "string",
"minLength": 42,
"maxLength": 42,
"pattern": "^0x[a-fA-F0-9]{40}$",
"description": "A valid Ethereum address (42 characters, starting with 0x)",
"examples": ["0x71C7656EC7ab88b098defB751B7401B5f6d8976F"]
},
"actorAddress": {
"type": "string",
"minLength": 42,
"maxLength": 42,
"pattern": "^0x[a-fA-F0-9]{40}$",
"description": "A valid Ethereum address (42 characters, starting with 0x)",
"examples": ["0x71C7656EC7ab88b098defB751B7401B5f6d8976F"]
},
"adminRoleId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"adminRoleFieldName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"blockNumber": {
"type": "string"
},
"chainId": {
"type": "integer",
"exclusiveMinimum": 0
},
"roleId": {
"type": "string"
},
"roleFieldName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"systemAddress": {
"type": "string",
"minLength": 42,
"maxLength": 42,
"pattern": "^0x[a-fA-F0-9]{40}$",
"description": "A valid Ethereum address (42 characters, starting with 0x)",
"examples": ["0x71C7656EC7ab88b098defB751B7401B5f6d8976F"]
},
"transactionHash": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{64}$"
}
},
"required": [
"accessManagerAddress",
"accountAddress",
"actorAddress",
"adminRoleId",
"adminRoleFieldName",
"blockNumber",
"chainId",
"roleId",
"roleFieldName",
"systemAddress",
"transactionHash"
],
"additionalProperties": true
}TypeScript SDK example
Use the request's raw body and headers with your endpoint's webhook secret. This handler illustrates verification and event selection. Before writing downstream state, deduplicate deliveries by evt_id and recognize replayed outcomes by their domain identifiers.
const result = await verifyWebhook({
rawBody,
headers,
secret: process.env.DALP_WEBHOOK_SECRET!,
});
if (!result.ok) {
throw new Error(`Webhook verification failed: ${result.code}`);
}
if (result.event.type === "access-control.role-granted.provisional") {
const event: Webhook.Event<"access-control.role-granted.provisional"> = result.event;
console.log(event.payload);
}HTTP delivery example
This illustrative request shows the delivery shape. Its timestamp and signature are placeholders; a verifier rejects them. Use a signed platform delivery to verify your endpoint.
curl -X POST https://consumer.example.com/dalp/webhooks \
-H "content-type: application/json" \
-H "webhook-id: evt_7c12e838e3f9a8bafcaa292f86ed41e7" \
-H "webhook-timestamp: 1778112000" \
-H "webhook-signature: v1,docs-example-signature" \
--data '{"evt_id":"evt_7c12e838e3f9a8bafcaa292f86ed41e7","source_id":"example:access-control.role-granted.provisional@2:0","lifecycle_state":"provisional","payload":{"accessManagerAddress":"0x1111111111111111111111111111111111111111","accountAddress":"0x2222222222222222222222222222222222222222","actorAddress":"0x3333333333333333333333333333333333333333","adminRoleId":"0x0000000000000000000000000000000000000000000000000000000000000000","adminRoleFieldName":"admin","blockNumber":"18445201","chainId":537001,"roleId":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","roleFieldName":null,"systemAddress":"0x4444444444444444444444444444444444444444","transactionHash":"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},"related":{},"type":"access-control.role-granted.provisional","version":2,"request":{"idempotency_key":"idem_01JZP7R5W8M9N0P1Q2R3S4T5"}}'Version and manifest
This page documents version 2 of access-control.role-granted.provisional. This event type is not deprecated. The DALP events manifest contains the machine-readable AsyncAPI entry.