Skip to main content

๐Ÿงฑ Call Surface

The execution model of pallet-xp is built on a simple architectural rule:

all logic lives in traits all public access happens through thin wrappers

This is called the call surface.

It defines how users, runtime modules, and external pallets reach XP logic without directly touching storage.

The pallet never follows:

User -> Extrinsic -> Direct Storage Write

Instead it follows:

User -> Wrapper Layer -> XP Traits -> Storage

and

Runtime -> Direct Trait Calls -> Storage

This separation is intentional.

Problem Without a Call Surfaceโ€‹

If extrinsics directly handled business logic:

  • logic gets duplicated
  • runtime integrations become difficult
  • testing becomes harder
  • pallets cannot safely reuse behavior
  • invariants become inconsistent

This creates fragile architecture.

Solution With a Call Surfaceโ€‹

All execution closes into:

XP Trait Engine

and every external interaction becomes only a controlled wrapper.

This gives:

BenefitResult
๐Ÿ”’ Single mutation enginepredictable behavior
โ™ป๏ธ Logic reuseeasier runtime composition
๐Ÿงช Better testingtraits tested independently
๐Ÿงฉ Modular designpallets integrate safely
โš™๏ธ Deterministic mutationno unsafe storage shortcuts

This is why the call surface is an architectural boundary, not just an API.


Traits First, Extrinsics Secondโ€‹

XP is not designed as an extrinsic-first pallet.

It is designed as a trait-first system.

The real execution engine is:

Core TraitResponsibility
XpSystemreads + validation
XpOwnerownership control
XpMutateXP growth + mutation
XpReservesoft constraints
XpLockhard constraints
XpReaplifecycle termination
BeginXpsafe lifecycle start

These traits define:

  • who owns XP
  • how XP grows
  • how constraints work
  • how lifecycle starts
  • how lifecycle ends

Why Extrinsics Are Thin Wrappersโ€‹

Users cannot call traits directly.

They need runtime access through signed transactions.

That means the pallet must provide:

User RequirementProvided By
Transaction signingExtrinsics
Origin verificationExtrinsics
Ownership checksExtrinsics
Permission enforcementExtrinsics
Event visibilityExtrinsics

But extrinsics should not own protocol logic.

They should only:

authenticate
-> validate
-> forward

Extrinsics provide access.

Traits provide behavior.


Three Call Surfaces

The architecture exposes three execution paths.

All three eventually reach the same XP trait engine.

1. Public Call Surface (User Extrinsics)โ€‹

This is how external users interact with XP.

Flow:

User
-> Signed Extrinsic
-> Validation Layer
-> XP Trait Execution
-> Storage Mutation

Users never mutate storage directly. They enter only through controlled wrappers.

Core Dispatchable Extrinsicsโ€‹

ExtrinsicArchitectural RoleFinal Trait Destination
call()XP-scoped executionruntime dispatch
handover()ownership transitionXpOwner
dispose()lifecycle finalizationXpReap
force_handover()governance overrideXpOwner
force_genesis_config()runtime parameter controlconfig updates

These are execution gateways, not business logic functions.

Example handover()โ€‹

The user calls:

handover(origin, xp_id, new_owner)

The extrinsic performs:

StepAction
1ensure_signed(origin)
2verify owner of xp_id
3validate destination
4call XpOwner::transfer_owner()
5emit event

The actual ownership mutation happens inside the trait. The extrinsic only protects access ๐Ÿ”


2. Internal Call Surface (Runtime Trait Access)โ€‹

Other pallets should not need extrinsics. They need direct composability.

This is why XP traits are runtime-native interfaces.

Flow:

Runtime Module
-> Direct Trait Call
-> XP Mutation
-> Storage

Example:

XpMutate::earn_xp(...)

This means:

  • no dispatch
  • no signed origin
  • no wrapper
  • only protocol composition

Common Runtime Operationsโ€‹

Runtime ActionTrait Function
Create XPbegin_xp()
Earn XPearn_xp()
Reserve XPset_reserve()
Lock XPset_lock()
Slash XPslash_xp()
Reap XPtry_reap()

This is where most real execution happens.

Not inside extrinsics.

Runtime Integratorsโ€‹

Typical integrations include:

SystemXP Usage
Governanceparticipation reputation
Stakingreserve / lock constraints
Missionscontributor progression
Validatorscommitment reputation
Participation Layersprotocol activity tracking

This is where XP becomes protocol-native.

The Special Case -> call()โ€‹

Among all extrinsics, call() is different.

It is not just a wrapper.

It is the architectural bridge between:

AccountId -> XpId

This is the center of the entire pallet ๐Ÿง 

What call() Actually Doesโ€‹

Dispatch Flowโ€‹

ensure_signed(origin)
-> verify owner(origin, xp_id)
-> elevate XpId into execution subject
-> dispatch RuntimeCall as Signed(XpId)

This transforms:

Signed(AccountId)

into:

Signed(XpId)

inside runtime execution. That transformation is what makes XP identity-native.

Without this, XP would only be metadata. With this, XP becomes execution itself.

Authority vs Executionโ€‹

LayerResponsibility
AccountIdsigns + authorizes
XpIdexecutes + mutates

Core rule:

๐Ÿ‘ค Account authorizes ๐Ÿง  XP executes

This is the architectural heart of pallet-xp.


3. Fungible Adapters Surfaceโ€‹

Some pallets do not use XP traits directly.

They expect standard Substrate balance interfaces:

frame_support::traits::fungible::*

Instead of forcing custom integrations, XP exposes fungible adapters.

This creates:

External Pallet
-> Fungible Adapter
-> XP Traits
-> Storage

Again:

Traits remain the real engine. Adapters are only wrappers.

Adapter Mappingโ€‹

External OperationInternal XP Trait
hold()set_reserve()
freeze()set_lock()
mint_into()set_xp()
burn_from()slash_xp()

This allows:

  • governance pallets
  • staking systems
  • hold/freeze integrations
  • standard Substrate pallets

to work with XP without custom rewrites.

Unified Call Surface Closureโ€‹

All execution paths eventually close into the same place:

XP Trait Engine

That closure guarantees:

GuaranteeWhy It Matters
One mutation engineconsistent execution
One validation modelsafer runtime behavior
One lifecycle systempredictable XP rules
One execution philosophyidentity-first design

This prevents fragmented logic. That is what makes the architecture safe.


Full Call Surface Architectureโ€‹

Everything ends in the same place:

XP trait execution

never direct storage mutation.

๐Ÿš€ Next Stepsโ€‹

To start using pallet-xp in your runtime, the next step is setting up the pallet and configuring its required dependencies.

๐Ÿ‘‰ Getting Started -> Installation