There are two ways to go about creating a conditional operation.
Using the if, then and else methods of the ConditionalOperation class.
Creating Condition objects and passing them to the constructor of the ConditionalOperation class.
1. Using the if, then and else methods
import { EVM } from "@kynesyslabs/demosdk/multichain/websdk"
import { prepareXMScript } from "@kynesyslabs/demosdk/websdk/XMTransactions"
import {
DemosWork,
prepareWeb2Step,
prepareXMStep,
ConditionalOperation,
} from "@kynesyslabs/demosdk/demoswork"
const address = "0x8A6575025DE23CB2DcB0fE679E588da9fE62f3B6"
const isMember = prepareWeb2Step({
url: `https://api.[redacted].com/v1/eth_sepolia/address/${address}`,
method: "GET",
})
// Web2 step to do a POST API call
const addMember = prepareWeb2Step({
url: `https://api.[redacted].com/v1/eth_sepolia/address/${address}?key=ckey_5a044cf0034a43089e6b308b023`,
method: "POST",
})
// XM step to send ETH
const evm = await EVM.create("https://rpc.ankr.com/eth_sepolia")
await evm.connectWallet(process.env.EVM_KEY)
const payload = await evm.prepareTransfer(address, "0.25")
const xmscript = prepareXMScript({
chain: "eth",
subchain: "sepolia",
type: "pay",
signedPayloads: [payload],
})
const releaseFunds = prepareXMStep(xmscript)
// Conditional operation
const operation = new ConditionalOperation()
operation
.if(isMember.output.statusCode, "==", 200)
.then(releaseFunds)
.else(addMember)
// Creating a DemosWork object and indexing the operation
const work = new DemosWork()
work.push(operation)
Using the Condition class
The Condition class can be used to construct a conditional operation without using the if, then and else methods.
Condition objects can be reused and combined to create more complex conditional operations.
A condition looks is implemented as follows:
import { operators } from "@kynesyslabs/demosdk/types"
class Condition {
value_a: any
operator: operators
value_b: any
action: WorkStep | DemosWorkOperation
}
The value_a and value_b fields are the operands of the condition. The operator field determines the type of condition. The action field is the work step or operation that will be executed if the condition is met.
The value_a and value_b fields can accept any of the following:
A work step or operation output
Another condition
A static value
You can create the same conditional operation as the previous example using the Condition class as follows:
import { EVM } from "@kynesyslabs/demosdk/multichain/websdk"
import { prepareXMScript } from "@kynesyslabs/demosdk/websdk/XMTransactions"
import {
Condition,
DemosWork,
prepareWeb2Step,
prepareXMStep,
ConditionalOperation,
} from "@kynesyslabs/demosdk/demoswork"
const address = "0x8A6575025DE23CB2DcB0fE679E588da9fE62f3B6"
const isMember = prepareWeb2Step({
url: `https://api.[redacted].com/v1/eth_sepolia/address/${address}`,
method: "GET",
})
// Web2 step to do a POST API call
const addMember = prepareWeb2Step({
url: `https://api.[redacted].com/v1/eth_sepolia/address/${address}?key=ckey_5a044cf0034a43089e6b308b023`,
method: "POST",
})
// XM step to send ETH
const evm = await EVM.create("https://rpc.ankr.com/eth_sepolia")
await evm.connectWallet(process.env.EVM_KEY)
const payload = await evm.prepareTransfer(address, "0.25")
const xmscript = prepareXMScript({
chain: "eth",
subchain: "sepolia",
type: "pay",
signedPayloads: [payload],
})
const releaseFunds = prepareXMStep(xmscript)
// Condition to check if the user is a member
const checkIsMember = new Condition({
value_a: isMember.output.statusCode,
operator: "==",
value_b: 200,
action: releaseFunds,
})
// Fallback condition (else)
const notMember = new Condition({
value_a: null,
operator: null,
value_b: null,
action: addMember,
})
// Creating a conditional operation
const operation = new ConditionalOperation(checkIsMember, notMember)
// Creating a DemosWork object and indexing the operation
const work = new DemosWork()
work.push(operation)
Combining conditions
You can combine conditions to create more complex conditions as shown below:
// equality
const booleanCondition = new Condition({
value_a: true,
operator: "==",
value_b: true,
})
// greater than
const greaterThanCondition = new Condition({
value_a: 10,
operator: ">",
value_b: 5,
})
// and
const combinedCondition = new Condition({
value_a: booleanCondition,
operator: "&&",
value_b: greaterThanCondition,
})
// not
const notCondition = new Condition({
value_a: booleanCondition,
operator: "not",
value_b: null,
})
Referencing web2 payloads in conditions
Web2 requests return various shapes of payload when executed, including plain text or JSON. Let's illustrate how you can reference these payloads using a GET request to read the current BTC price.
The value we can use in a condition is nested inside the bitcoin object under the usd key. We can reference the value as shown below:
new Condition({
value_a: getBTCPrice.output["bitcoin.usd"],
...
})
When dealing with web2 endpoints that return a single value, eg. a string or number, or when you want to reference the whole payload, you can do the following:
new Condition({
value_a: getBTCPrice.output,
...
})