@onflow/interaction
This module provides an ADT (Abstract Data Type) that represents the underlying data required by the send
function. It provides function in which to modify the interaction.
Install
npm install --save @onflow/interaction
Types of interactions
Currently the Access Node recognizes 7 different types of interactions.
- Script executes a script, can be used to query Flow
- Transaction executes a transaction
- GetTransactionStatus requests the status of a supplied transaction
- GetAccount requests a supplied account
- GetEvents requests events of a supplied type
- GetLatestBlock requests the latest block
- Ping requests a pong
Internal Properties
The interaction is a monomorphic data structure, that merges the 7 types of interactions together. Internally it has a bunch of properties, but not everything needs to be included for each of the 7 interaction types.
- tag (all)
Int
-- a marker that represents the type of the interaction - status (all)
Int
-- a marker that represents the status of the interaction - reason (all)
String
-- used to supply more information/feedback when a status is bad - payload (script, transaction)
- code (script, transaction)
String
-- cadence code - ref (transaction)
String
-- id of an existing block (used for timeout) - nonce (transaction)
Int
-- all transactions in Flow need to be unique - limit (transaction)
Int
-- how much payer is willing to spend
- bounds (getEvents)
- start (getEvebts)
Int
-- events after this - end (getEvents)
Int
-- events before this
- acct (getAccount)
String
-- the account to get - authz (transaction)
Array<{acct:String, signature:String, keyId:Int}>
-- list of accounts and signatures authorizing a transaction - proposer (transaction)
{acct:String, keyId:Int, sequenceNum:Int}
-- the proposer for a transaction - payer (transaction)
{addr:String, signature:String, keyId:Int}
-- which account is paying for the transaction and their authorization - eventType (getEvents)
String
-- the type of events to query against - txId (getTransaction)
String
-- id of the transaction to query against - isSealed (getLatestBlock)
Boolean
-- determines if the criteria for the latest block is sealed or FIND_CORRECT_STATE_NAME - assigns (all)
{[String]:Any}
-- a pocket to hold things in while building and resolving
Exposed Constants
Tags
Label | asInt | asBin |
---|
UNKNOWN | 1 | 0b00000001 |
SCRIPT | 2 | 0b00000010 |
TRANSACTION | 4 | 0b00000100 |
GET_TRANSACTION_STATUS | 8 | 0b00001000 |
GET_ACCOUNT | 16 | 0b00010000 |
GET_EVENTS | 32 | 0b00100000 |
GET_LATEST_BLOCK | 64 | 0b01000000 |
PING | 128 | 0b10000000 |
Status
Label | asInt | asBin |
---|
BAD | 1 | 0b01 |
OK | 2 | 0b10 |
Exposed Functions
- Constructor
- Control
- Tags
- Unknown
- Script
- Transaction
- GetTransactionStatus
- GetAccount
- GetEvents
- GetLatestBlock
- Ping
- Assigns
- Composition
interaction/0
Constructs an empty interaction.
import {interaction} from "@onflow/interaction"
const emptyInteraction = interaction()
isInteraction/1
returns true if the value passed to it is an interaction
import {interaction, isInteraction} from "@onflow/interaction"
const ix = interaction()
isInteraction(ix)
isInteraction("i am a string")
Ok/1
and isOk/1
Sets the status of an interaction to OK
import {interaction, Ok, isOk} from "@onflow/interaction"
isOk(Ok(interaction()))
Bad/2
, isBad/1
and why/1
Sets the status of an interaction to BAD
, can also add a reason as to why its bad.
import {interaction, Bad, why} from "@onflow/interaction"
const ix = Bad(interaction, "You were supposed to do the thing")
isBad(ix)
why(ix)
makeUnknown/1
and isUnknown/1
tags an interaction as Unknown
import {interaction, makeUnknown, isUnknown} from "@onflow/interaction"
isUnknown(makeUnknown(interaction()))
makeScript/1
and isScript/1
tags an interaction as a Script interaction
import {interaction, makeScript, isScript} from "@onflow/interaction"
isScript(makeScript(interaction()))
makeTransaction/1
and isTransaction/1
tags an interaction as a Transaction interaction
import {interaction, makeTransaction, isTransaction} from "@onflow/interaction"
isTransaction(makeTransaction(interaction()))
makeGetTransaction/1
and isGetTransaction/1
tags an interaction as a GetTransactionStatus interaction
import {interaction, makeGetTransactionStatus, isGetTransactionStatus} from "@onflow/interaction"
isGetTransactionStatus(makeGetTransactionStatus(interaction()))
makeGetAccount/1
and isGetAccount/1
tags an interaction as a GetAccount interaction
import {interaction, makeGetAccount, isGetAccount} from "@onflow/interaction"
isGetAccount(makeGetAccount(interaction()))
makeGetEvents/1
and isGetEvents/1
tags an interaction as a GetEvents interaction
import {interaction, makeGetEvents, isGetEvents} from "@onflow/interaction"
isGetEvents(makeGetEvents(interaction()))
makeGetLatestBlock/1
and isGetLatestBlock/1
tags an interaction as a GetLatestBlock interaction
import {interaction, makeGetLatestBlock, isGetLatestBlock} from "@onflow/interaction"
isGetLatestBlock(makeGetLatestBlock(interaction()))
makePing/1
and isPing/1
tags an interaction as a Ping interaction
import {interaction, makePing, isPing} from "@onflow/interaction"
isPing(makePing(interaction()))
get/3
, put/2
, update/2
and destory/1
crud operations for the assigns pocket inside the interaction. They are specifically designed to be used with pipe
.
import {interaction, get, put, update, destory} from "@onflow/interaction"
let ix = interaction()
get(ix, "count", 0)
ix = put("count", 0)(ix)
get(ix, "count", 0)
ix = update("count", count => count + 1)(ix)
get(ix, "count", 0)
ix = destory("count")(ix)
get(ix, "count", 0)
pipe/2
asynchronously composes transform functions and applys them to an interaction.
import {interaction, pipe, put, update} from "@onflow/interaction"
const ix = await pipe(interaction(), [
put("a", 5),
put("b", 6),
update("sum", (_, ix) => get(ix, "a", 0) + get(ix, "b", 0))
])
get(ix, "sum", 0)
pipe/1
gets passed an array of transform functions, returning a function that takes an interaction to apply the transform functions to asynchronously.
import {interaction, pipe, put, update} from "@onflow/interaction"
const run = await pipe([
put("a", 5),
put("b", 6),
update("sum", (_, ix) => get(ix, "a", 0) + get(ix, "b", 0))
])
const ix = run(interaction())
get(ix, "sum", 0)
const p1 = pipe([
put("a", 1),
put("b", 2),
])
const p2 = pipe([
put("c", 3),
put("d", 4),
])
const calc = update("sum", (_, ix) => ["a", "b", "c", "d"].reduce((acc, d) => acc + get(ix, d, 0), 0))
const ix = await pipe(interaction(), [p1, p2, calc])
get(ix, "sum", 0)
import { Bad, Ok, isBad, why } from "@onflow/interaction"
const countCantBeGreaterThan = value => ix =>
get(ix, "count", 0) > value
? Bad(ix, `Was greater than ${value}`)
: Ok(ix)
const setCount = count => put("count", count)
const incCountBy = amount => update("count", (count) => count + amount)
const ix = await pipe(interaction(), [
setCount(5),
countCantBeGreaterThan(10),
incCountBy(3),
countCantBeGreaterThan(10),
incCountBy(5),
countCantBeGreaterThan(10),
incCountBy(9),
])
isBad(ix)
why(ix)