Actions
Transfers are great when we want to send money to an account, but what if we want to send a message? — Actions fill that gap. Actions look very similar to transfers, but they do not contain an amount. Instead, they contain a payload, an arbitrary blob of bytes. Let's look at a few use cases for actions that might further elucidate their usefulness.
Requests
The ledger already has support for sending money to another account, but how do you ask for money from an account? Say you run a yard-work business and need to invoice your client. Actions are M10's answer to this problem. We simply need to create an action with the "target" set to the account you want to request money from. The payload will need to be in a well-known format. This is such a common use case that we include such a format in our SDK. It's defined by the following protobuf.
You'll notice there is a "status" enum included in the above model. That is so the requester - and requestee - can keep track of the current status of the request.
RPC
Another common use case for actions is as a sort of on-ledger remote-procedure call. Imagine that an FX provider is running on the ledger, kind of you want to get a quote for an FX swap between two currencies. You could simply send an action to that provider's account with a quote request message. The FX provider would then send a response back that you could observe.
Observations
Observations are one of the key building blocks of the ledger. They are a way to receive a stream of events relating to a certain type. Actions are most useful when observed in real-time. Take for example the FX provider talked about above. Observations allow the FX provider to be notified when it receives an action.
When combined with observations, actions become close to a distributed queue (like Kafka). Observations allow you to specify a starting txn id to observe from. You will then receive a stream of all the actions to occur since that txn-id. This allows you to have at-least-once semantics for messages delivered on the ledger! All without an external service.
Model
API Calls
Invoke
Actions are identified using the name
parameter. When invoked
they can be sent to a specific account using Target::Account
or broadcast to all using Target::AnyAccount
.
- Rust
- TS
- Dart
- CLI
Get
- Rust
- TS
- CLI
List
Actions can be filtered based on a specific account ID involved, e.g. the from
or target
parameters, or based on a context ID.
- Rust
- TS
- Dart
- CLI
Observe
Actions can be observed based on a list of specific account IDs involved, e.g. the from
or target
parameters.
If any of the account IDs provided are matched, the relevant action will be observed.
It is recommended to use a separate client instance for streaming. Name and involved accounts are required filter parameters to receive actions from subscriptions.
- Rust
- TS
- Dart
- CLI