Skip to main content

Intent Components

Intents consist of different components that dictate what actions will be executed once the intent reaches the specified block height. Components can include transfers, contract calls, IBC messages, or claims. Each component is handled individually based on its type.

Overview of Intent Components

The core types of intent components include:

  • Execution Components: These handle actual execution actions like token transfers, contract calls, or IBC messages.
  • Claim Components: Components that can be claimed by a specific user after the intent expires.

Execution Components

Execution components are triggered automatically when the intent reaches its target height. Each component is handled based on its type.

Token Transfers

A token transfer is a common execution component. Here's how it's processed in the BeginBlocker:

switch component.ComponentType.(type) {
case *types.ExecutionComponent_Transfer:
k.ExecuteTransfer(ctx, component, *will)
component.Status = "executed"
}

The transfer component logic is handled in the ExecuteTransfer function:

func (k Keeper) ExecuteTransfer(ctx sdk.Context, component *types.ExecutionComponent, will types.Will) error {
coins := sdk.NewCoins(*component.GetTransfer().Amount)
fromAddr := sdk.AccAddress(will.Creator)
toAddr := sdk.AccAddress(component.GetTransfer().To)

return k.bankKeeper.SendCoins(ctx, fromAddr, toAddr, coins)
}

Contract Calls

Contract calls are another component type, allowing intents to execute contract logic:

case *types.ExecutionComponent_Contract:
k.ExecuteContract(ctx, component.GetContract(), will.Creator)
component.Status = "executed"

Contract execution is managed in ExecuteContract:

func (k Keeper) ExecuteContract(ctx sdk.Context, contract *types.ExecutionComponent_Contract, caller string) ([]byte, error) {
contractAddr := sdk.AccAddress(contract.Address)
callerAddr := sdk.AccAddress(caller)

return k.permissionedWasmKeeper.Execute(ctx, contractAddr, callerAddr, contract.Data, sdk.NewCoins())
}

IBC Messages

Intents can also send IBC messages as part of their execution:

case *types.ExecutionComponent_IbcMsg:
k.SendIBCMessage(ctx, component, *will)
component.Status = "executed"

The SendIBCMessage function constructs and sends an IBC packet:

func (k *Keeper) SendIBCMessage(ctx sdk.Context, component *types.ExecutionComponent, will types.Will) error {
packet := channeltypes.NewPacket(component.GetIbcMsg().Data, sequence, "will", component.GetIbcMsg().Channel, timeoutHeight, timeoutTimestamp)
return k.channelKeeper.SendPacket(ctx, channelCap, "will", component.GetIbcMsg().Channel, packet)
}

Claim Components

Claim components can only be activated after the intent has expired. These components can be claimed by users, provided they meet the necessary criteria and pass verification.

The claim is processed like this:

case *types.ExecutionComponent_Claim:
component.Status = "active" // Mark as claimable after expiration

Once marked as active, a user can submit a claim via the Claim function. The verification process will ensure the user has the right to claim the component, either through Schnorr signatures, Pedersen commitments, or other supported mechanisms.

By structuring intents with these various components, Rugsafe's chain allows for a flexible and secure execution of decentralized logic.