Resources
SoulGrant is the on-chain access delegation system for Soulidity. It lets the Soul owner authorize AI agents or other wallets to read Seal-protected content, append memory entries, publish skill versions, or manage private asset versions — without transferring ownership.
Every grant carries a scope_mask — a bitfield that determines which Soul data channels the grantee can access. Scopes are additive and can be combined.
| Constant | Value | Grants access to |
|---|---|---|
| SCOPE_SEAL | 1 | Decrypt the Soul content blob via Seal |
| SCOPE_MEMORY | 2 | Read encrypted memory entries and append new ones |
| SCOPE_SKILLS | 4 | Read private skill versions and publish new ones |
| SCOPE_ASSETS | 8 | Read private asset versions and publish new ones |
To grant all four scopes, use scope_mask = 15 (1 | 2 | 4 | 8). The Move module rejects a mask of 0 and any bits outside these four scope bits.
grant::issue on-chain, passing the SoulState, grantee address, scope mask, and optional expiry timestamp in milliseconds. One grant slot per grantee is enforced — issuing a second grant to the same grantee supersedes the first. The default grant_capacity is 1.grant::revoke_scope to strip specific scope bits and issue a replacement grant in one atomic transaction. The event log records both SoulGrantSuperseded and a new SoulGrantIssued.grant::revoke to remove a grantee's slot entirely. Emits SoulGrantRevoked.expires_at_ms is set, the grant silently fails validation once the Sui clock passes that timestamp. Expired grants are cleaned up lazily on the next write operation. Emits SoulGrantExpired.SoulGrantInvalidated. The ownership_epoch_snapshot on the grant object must match the current SoulState.ownership_epoch for validation to pass.public struct SoulGrant has key, store {
id: UID,
soul_id: ID,
grantee: address,
issued_by: address,
ownership_epoch_snapshot: u64, // invalidated on ownership transfer
scope_mask: u64,
expires_at_ms: Option<u64>,
}The SoulGrant object is transferred to the grantee wallet after grant::issue. The grantee must pass it as an argument to any guarded Move entry function. The ownership_epoch_snapshot must equal the current SoulState.ownership_epoch — any ownership rotation increments the epoch and invalidates all outstanding grants.
txDigest — the Sui transaction digestaction — "issue" | "revoke" | "revoke-scope"granteeAddress — required for revoke and revoke-scope actionsgrantOnChainId, activeGrantCount, and the TX digest. Idempotent — replaying the same txDigest returns the cached response.activeGrantCount from the DB mirror. To read live on-chain grant state use the Soulidity SDK query helpers.When a viewer calls an access route (Soul content, memory, skills), the server runs resolveSoulAccessPayload / resolveMemoryAccessPayload:
SoulState from chain to get the current owner and active grant list.seal_approve_owner approval params.activeGrants for a slot whose granteeAddress matches and whose scopes includes the required scope.SoulGrant object from chain and validate expiry and ownership epoch.seal_approve_granted_agent approval params with the grant object ID.