@onflow/interaction
v0.0.11
Published
Flow Interaction ADT and Helpers
Downloads
61,564
Maintainers
Keywords
Readme
@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.
Status
- Last Updated: Feb 2nd 2021
- Stable: Yes
- Risk of Breaking Change: Medium
This is a keystone data structure in how the SDK works. We will strive for backwards compatibility in any changes to this, as it also makes our lives easier. Now that we have a stable encoding package for creating what needs to be signed in transactions, we will be bringing this data structure closer to what those functions need.
Known Upcoming Changes:
- We will be changing some of the underlying fields and data so they are more inline with
@onflow/encode
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
- GetTransaction requests a transaction
- GetBlockById requests a block by an ID deprecated, use GetBlock instead
- GetBlockByHeight requests a block by a height deprecated, use GetBlock instead
- GetBlock requests a block
- GetBlockHeader requests a block header
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 - accounts (transaction, script)
- kind (transaction, script)
Int
-- denotes the kind of account, ACCOUNT or PARAM or ARGUMENT - tempId (transaction, script)
String
-- denotes the internal tempId for this account - addr (transaction, script)
String
-- denotes the address of this account - keyId (transaction, script)
Int
-- denotes the keyId in question for this account - sequenceNum (transaction, script)
Int
-- denotes the sequenceNum in question for this account - signature (transaction, script)
String
-- the signature produced by the signingFunction for this account - signingFunction (transaction, script)
Function
-- the signing function for this account - resolve (transaction, script)
Function
-- the resolver for this account - role (transaction, script)
- propser (transaction, script)
Boolean
-- denotes if this account is a propser - authorizer (transaction, script)
Boolean
-- denotes if this account is an authorizer - payer (transaction, script)
Boolean
-- denotes if this account is a payer - param (transaction, script)
Boolean
-- denotes if this account is a param
- propser (transaction, script)
- kind (transaction, script)
- params (transaction, script)
- kind (transaction, script)
Int
-- denotes the kind of param, ACCOUNT or PARAM or ARGUMENT - tempId (transaction, script)
String
-- the internal tempId for this param - key (transaction, script)
String
-- the key for this param - value (transaction, script)
Any
-- the value for this param - asParam (transaction, script)
Any
-- the asParam transformed value for this param - xform (transaction, script)
Any
-- the transform for this param - resolve (transaction, script)
Function
-- a resolver for this param
- kind (transaction, script)
- arguments (transaction, script)
- kind (transaction, script)
Int
-- denotes the kind of argument, ACCOUNT or PARAM or ARGUMENT - tempId (transaction, script)
String
-- the internal tempId for this argument - value (transaction, script)
Any
-- the value for this argument - asArgument (transaction, script)
Any
-- the asArgument transformed value for this argument - xform (transaction, script)
Any
-- the transform for this argument - resolve (transaction, script)
Function
-- a resolver for this argument
- kind (transaction, script)
- message (script, transaction)
- cadence (script, transaction)
String
-- cadence code - refBlock (transaction)
String
-- id of an existing block (used for timeout) - computeLimit (script)
Int
-- how much payer is willing to spend - proposer (transaction)
String
-- the tempId of the account proposer for a transaction - payer (transaction)
String
-- the tempId of the payer for a transaction - authorizations (transaction)
Array<String>
-- list of tempIds referencing the accounts of the authorizers for a transaction - params (transaction, script)
Array<String>
-- list of tempIds referencing the params for a transaction or script - arguments (transaction, script)
Array<String>
-- list of tempIds referencing the arguments for a transaction or script
- cadence (script, transaction)
- proposer (transaction)
String
-- the tempId referencing the account of the proposer for a transaction - payer (transaction)
String
-- the tempId referencing the account of the payer for a transaction - authorizations (transaction)
Array<String>
-- list of tempIds referencing the accounts of the authorizers for a transaction - events (getEvents)
- start (getEvents)
Int
-- events after this - end (getEvents)
Int
-- events before this - eventType (getEvents)
String
-- type of events to get - blockIds (getEvents)
Array<String>
-- array of block ids to get events from
- start (getEvents)
- block (getLatestBlock, getBlockByHeight, getBlockById)
- isSealed (getLatestBlock)
Boolean
-- determines if the criteria for the latest block is sealed or not. - height (getBlockByHeight)
Int
-- sets the height for the block to get. - id (getBlockById)
Int
-- sets the id for the block to get.
- isSealed (getLatestBlock)
- account
- addr _(getAccount)
String
-- address of the account to get
- addr _(getAccount)
- transaction
- id _(getTransaction) -- id of the transaction to get
- assigns (all)
{[String]:Any}
-- a pocket to hold things in while building and resolving
Exposed Constants
Tags
| Label | asString | | ----------------------: | :-------------------------: | | UNKNOWN | UNKNOWN | | SCRIPT | SCRIPT | | TRANSACTION | TRANSACTION | | GET_TRANSACTION_STATUS | GET_TRANSACTION_STATUS | | GET_ACCOUNT | GET_ACCOUNT | | GET_EVENTS | GET_EVENTS | | GET_LATEST_BLOCK | GET_LATEST_BLOCK | | PING | PING | | PING | PING | | GET_TRANSACTION | GET_TRANSACTION | | GET_BLOCK_BY_ID | GET_BLOCK_BY_ID | | GET_BLOCK | GET_BLOCK | | GET_BLOCK_HEADER | GET_BLOCK_HEADER |
Status
| Label | asString | | ----: | :------: | | BAD | BAD | | OK | OK |
Exposed Functions
- Constructor
- Control
- Tags
- Unknown
- Script
- Transaction
- GetTransactionStatus
- GetAccount
- GetEvents
- GetLatestBlock
- GetBlock
- Ping
- GetTransaction
- GetBlock
- GetBlockHeader
- Assigns
- Accounts
- Params
- 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) // true
isInteraction("i am a string") // false
Ok/1
and isOk/1
Sets the status of an interaction to
OK
import {interaction, Ok, isOk} from "@onflow/interaction"
isOk(Ok(interaction())) // true
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) // true
why(ix) // "You were supposed to do the thing"
makeUnknown/1
and isUnknown/1
tags an interaction as Unknown
import {interaction, makeUnknown, isUnknown} from "@onflow/interaction"
isUnknown(makeUnknown(interaction())) // true
makeScript/1
and isScript/1
tags an interaction as a Script interaction
import {interaction, makeScript, isScript} from "@onflow/interaction"
isScript(makeScript(interaction())) // true
makeTransaction/1
and isTransaction/1
tags an interaction as a Transaction interaction
import {interaction, makeTransaction, isTransaction} from "@onflow/interaction"
isTransaction(makeTransaction(interaction())) // true
makeGetTransaction/1
and isGetTransaction/1
tags an interaction as a GetTransactionStatus interaction
import {
interaction,
makeGetTransactionStatus,
isGetTransactionStatus,
} from "@onflow/interaction"
isGetTransactionStatus(makeGetTransactionStatus(interaction())) // true
makeGetAccount/1
and isGetAccount/1
tags an interaction as a GetAccount interaction
import {interaction, makeGetAccount, isGetAccount} from "@onflow/interaction"
isGetAccount(makeGetAccount(interaction())) // true
makeGetEvents/1
and isGetEvents/1
tags an interaction as a GetEvents interaction
import {interaction, makeGetEvents, isGetEvents} from "@onflow/interaction"
isGetEvents(makeGetEvents(interaction())) // true
makeGetLatestBlock/1
and isGetLatestBlock/1
tags an interaction as a GetLatestBlock interaction
import {
interaction,
makeGetLatestBlock,
isGetLatestBlock,
} from "@onflow/interaction"
isGetLatestBlock(makeGetLatestBlock(interaction())) // true
makePing/1
and isPing/1
tags an interaction as a Ping interaction
import {interaction, makePing, isPing} from "@onflow/interaction"
isPing(makePing(interaction())) // true
makeGetTransaction/1
and isGetTransaction/1
tags an interaction as a GetTransaction interaction
import {interaction, makeGetTransaction, isGetTransaction} from "@onflow/interaction"
isGetTransaction(makeGetTransaction(interaction())) // true
makeGetBlock1
and isGetBlock/1
tags an interaction as a GetBlock interaction
import {interaction, makeGetBlock, isGetBlock} from "@onflow/interaction"
isGetBlock(makeGetBlock(interaction())) // true
makeGetBlockHeader/1
and isGetBlockHeader/1
tags an interaction as a GetBlockHeader interaction
import {interaction, makeGetBlockHeader, isGetBlockHeader} from "@onflow/interaction"
isGetBlockHeader(makeGetBlockHeader(interaction())) // true
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) // 0
ix = put("count", 0)(ix)
get(ix, "count", 0) // 0
ix = update("count", count => count + 1)(ix)
get(ix, "count", 0) // 1
ix = destory("count")(ix)
get(ix, "count", 0) // 0
makeAuthorizer/1
compose an Authorizer account, and registers a tempId for it in the interaction object accounts registry
import {makeAuthorizer, makeTransaction, pipe} from "@onflow/interaction"
const ix = pipe([
makeTransaction``
makeAuthorizer({ addr: "01", role: { authorizer: true } })
])
makePayer/1
compose a Payer account, and registers a tempId for it in the interaction object accounts registry
import {makePayer, makeTransaction, pipe} from "@onflow/interaction"
const ix = pipe([
makeTransaction``
makePayer({ addr: "01", role: { payer: true } })
])
makeProposer/1
compose a Proposer account, and registers a tempId for it in the interaction object accounts registry
import {makeProposer, makeTransaction, pipe} from "@onflow/interaction"
const ix = pipe([
makeTransaction``
makeProposer({ addr: "01", role: { proposer: true } })
])
makeParam/1
compose a Param, and registers a tempId for it in the interaction object params registry
import {makeParam, makeTransaction, pipe} from "@onflow/interaction"
const ix = pipe([
makeTransaction``
makeParam(...)
])
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) // 11
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) // 11
// Pipes can also be composed
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) // 10
// Pipes can be stoped
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), // count: 5
countCantBeGreaterThan(10), // Ok
incCountBy(3), // count: 8
countCantBeGreaterThan(10), // Ok
incCountBy(5), // count: 13
countCantBeGreaterThan(10), // Bad
incCountBy(9), // never called
])
isBad(ix) // true
why(ix) // "Was greater than 10"