Code samples

This sections contains different ParsiQL code samples

Ethereum

Uniswap Swap spikes

The following Smart-Trigger allows to monitor a defined Table of Uniswap Pair Pools, perform calculations and detect Swap spikes according to threshold.

In this example we observe the PRQ/ETH Pair's Pool and set the ETH (WETH to be precise) as the trading asset (TradingAsset) to set the thresholds against.

User Data

Table for storing Uniswap Pairs Pool data

Smart-Trigger

stream UniswapSwapSpikes
# We are interested in the Token Transfers for the Uniswap case.
from TokenTransfers
# We have a table with (interesting to us) Uniswap Pools. We want to monitor both BUYs and SELLs for them.
where @to in UniswapPools || @from in UniswapPools
process
# Basic initialization variable for later usage
let threshold = 0
let initiator = 0x0
let pool = 0x0
let action = ""
# If our Trading Asset is used for BUY operation
if @to in UniswapPools && @code_address == UniswapPools[@to].TradingAsset then
threshold = UniswapPools[@to].BuyThreshold
# The address that initiated the BUY operation
initiator = @from
# The pool that was
pool = @to
action = "BUY"
# If our Trading Asset is used for SELL operation
elseif @from in UniswapPools && @code_address == UniswapPools[@from].TradingAsset then
threshold = UniswapPools[@from].SellThreshold
initiator = @to
pool = @from
action = "SELL"
end
# Check that BUY or SELL happened
if action != "" then
# Additional check that we are dealing with ERC-20'ies
if @is_erc20 then
# We compare that the BUY/SELL amount is exceeding the defined (Buy/Sell)Threshold
if compare({value: @value, decimals: @erc20.decimals}, {value: threshold, decimals: 0}) >= 0 then
emit {@value, initiator, pool: UniswapPools[pool].Details, threshold, action, currency: @erc20.symbol, decimals: @erc20.decimals}
end
else
emit {@value, initiator, pool: UniswapPools[pool].Details, threshold, action, currency: "?", decimals: 18}
end
end
end

Uniswap PRQ Spikes

This Smart-Trigger is a more simple and specific solution to the same task as in "Uniswap Swap spikes", only that it monitors Uniswap spikes specifically for PRQ/ETH Pair Pool against ETH (WETH to be precise)

User Data

Uniswap spike threshold values against PRQ and ETH separately
A Primitive Record to store WETH's Smart-Contract address
A Struct Record of fields that hold some PRQ related addresses

Smart-Trigger

stream PRQTransfers
from TokenTransfers
where @code_address == WETH && @to == PRQTrackingData.UniswapAddress
process
if compare({value: @value, decimals: @erc20.decimals}, {value: UniswapSpikeThreshold.ETH, decimals: 0}) >= 0 then
emit {@value, @to, @from, decimals: @erc20.decimals, current_spike_threshold: UniswapSpikeThreshold.ETH, currency: @erc20.symbol}
end
end

PRQ Whale Transfers

The following ParsiQL code stands behind the Flashr (PRQ Project to be precise in this example) that is a sub-product of PARSIQ Monitoring and is completely based on the Public Project feature. It allows to monitor all PRQ TokenTransfers with a defined threshold that is large enough to be counted as a whale one.

User Data

Smart-Trigger

stream WhaleTransfers
from TokenTransfers
where @code_address == PRQ.ContractAddress
process
if compare({@value, decimals: @erc20.decimals}, {value: PRQ.WhaleTransferThreshold, decimals: 0}) >= 0 then
let description = "PARSIQ (" + @erc20.symbol + ") Whale Transfers"
let cryptorankFiatRate = getRate(@erc20.symbol)
let fiat_value = @value * cryptorankFiatRate.value
let fiat_decimals = @erc20.decimals + cryptorankFiatRate.decimals
emit {@to, @from, @value, decimals: @erc20.decimals, symbol: @erc20.symbol, description, fiat_value, fiat_decimals}
end
end

PARSIQ Foundation Wallets monitoring

As with task in "PRQ Whale Transfers" - this one is also used behind Flashr and aims to monitor a set of PARSIQ Foundation Wallets.

Notice, that the stored User Data (for addresses table) is accessible via the public API for this particular Public Project

User Data

Smart-Trigger

stream FoundationTransfers
from TokenTransfers
where @code_address == PRQ.ContractAddress
where @to in addresses || @from in addresses
process
let toNote = ""
let fromNote = ""
if @to in addresses then
toNote = addresses[@to].label
fromNote = "origin"
else
toNote = "destination"
fromNote = addresses[@from].label
end
let description = "PARSIQ (" + @erc20.symbol + ") Foundation Transfers"
let cryptorankFiatRate = getRate(@erc20.symbol)
let fiat_value = @value * cryptorankFiatRate.value
let fiat_decimals = @erc20.decimals + cryptorankFiatRate.decimals
emit {@to, @from, toNote, fromNote, @value, decimals: @erc20.decimals, symbol: @erc20.symbol, description, fiat_value, fiat_decimals}
end

Ocean Protocol Datatoken Accounting

This example shows how one can have multiple Datatokens and aggregate the volume of Datatokens used as a payment for specifc Dataset (matched against CorporateDatatokens Table Record) consumptions.

Smart-Trigger

stream CorporateDatasetAccounting
# Stream all possible Dataset consumes on the Ocean Protocol
from OceanDatasetConsumes
# Filter those that match our Datatokens
where @dataToken in CorporateDatatokens
process
# Initialize Datatoken volumes to 0
state labelledAnimalImagesDatatokenVolume = 0
state ebayProductsDatatokenVolume = 0
# Detect Dataset
let dataset = CorporateDatatokens[@dataToken].Dataset
let volumeToSendViaAPI = 0
if dataset == "Labelled Animal Images" then
# Update volume in case of first Dataset
labelledAnimalImagesDatatokenVolume += @amount
volumeToSendViaAPI = labelledAnimalImagesDatatokenVolume
# Emit results
emit {..., volumeToSendViaAPI, decimals: 18, dataset}
elseif dataset == "Ebay Products" then
# Update volume in case of second Dataset
ebayProductsDatatokenVolume += @amount
volumeToSendViaAPI = ebayProductsDatatokenVolume
# Emit results
emit {..., volumeToSendViaAPI, decimals: 18, dataset}
end
end

In this example, specifically for ETH/USD pair.

Smart-Trigger

stream EthUsdPriceUpdates
from ChainlinkPriceFeed
where @pair == "ETH/USD"
process
let eth_usd_pair = getChainlinkPriceFeedPair("ETH/USD")
emit {..., eth_usd_pair}
end

Compliance Wallet Tracker for CryptoPay

A Smart-Trigger that allows to set-up a multi-layer compliance protection for a fictional company, called "CryptoPay".

User Data

Smart-Trigger

# Our named Event Stream of "ClientTransfers"
stream ClientTransfers
# The Native Event Stream of ETH Transfers
from Transfers
# We are interested in deposits and withdrawals among our clients
where @to in ClientWallets || @from in ClientWallets
# We are interested in ETH Transfers that are more than our predefined MinimumTransfer
where compare({@value, decimals: 18}, {value: TrackingConfiguration.MinimumTransfer, decimals: 0}) > 0
process
# Accumulate IN- and OUT circulation volume among our clients
state totalInflow = 0
state totalOutflow = 0
# Our client address
let target = 0x0000000000000000000000000000000000000000
# Other party of transfer
let counterparty = 0x0000000000000000000000000000000000000000
if @to in ClientWallets then
totalInflow += @value
target = @to
counterparty = @from
elseif @from in ClientWallets then
totalOutflow += @value
target = @from
counterparty = @to
end
# Retrieve categorial risk score from Uppsala for non-client
let uppsalaRiskScore = getSentinelProtocolData("ETH", counterparty)
# 1st layer security. We start gathering more data in case of non-whitelisted result (greylist, blacklist or other)
if uppsalaRiskScore.securityCategory != "whitelist" then
# Retrieve numerical risk score from Crystal for non-client
let crystalRiskScore = getCrystalDataForETH(counterparty)
# 2nd layer security. We fire a compliance ALERT in case Crystal risk score is more than predefined AllowedRiskScore
if compare(crystalRiskScore.decimalRiskScore, {value: TrackingConfiguration.AllowedRiskScore, decimals: 2}) > 0 then
# Emit an ALERT
emit {type: "ALERT", @from, @to, @value, targetLabel: ClientWallets[target].Label, targetID: ClientWallets[target].ID}
else
# Just emit a NOTIFICATION
emit {type: "NOTIFICATION", @from, @to, @value, targetLabel: ClientWallets[target].Label, targetID: ClientWallets[target].ID}
end
else
# Just emit a NOTIFICATION
emit {type: "NOTIFICATION", @from, @to, @value, targetLabel: ClientWallets[target].Label, targetID: ClientWallets[target].ID}
end
end

Binance Smart Chain

PancakeSwap volume aggregator for TWT/WBNB pair

In this particular case - we would like to aggregate the volume of TWT Tokens swapped in the context of TWT/WBNB Pair (BSC scan link) and then compare two approaches to calculating according USD volume: continuously or post factum.

User Data

Smart-Trigger

stream PancakeSwapTradesForTWTBNB
# We are interested in the BEP20 Token Transfers for the PancakeSwap case.
from BscBEP20Transfers
# We have a table with (interesting to us) PancakeSwap Pairs. We want to monitor both BUYs and SELLs for them.
where @to in PancakeSwapPairs || @from in PancakeSwapPairs
# Filter out everything except TWT/WBNB
where @to in PancakeSwapPairs && PancakeSwapPairs[@to].Pair == "TWT/WBNB" || @from in PancakeSwapPairs && PancakeSwapPairs[@from].Pair == "TWT/WBNB"
process
state startingBlock = 0
state buyVolumeTWT = 0
state sellVolumeTWT = 0
state buyVolumeInUSD = {value: 0, decimals: 0}
state sellVolumeInUSD = {value: 0, decimals: 0}
# Basic initialization variable for later usage
let initiator = 0x0
let pair = 0x0
let action = ""
let TWTinUSD = {value: 0, decimals: 0}
if startingBlock == 0 then
startingBlock = @block.number
end
let cryptorankPriceInUSDforTWT = {value: 0, decimals: 0}
if @token.symbol == "TWT" then
cryptorankPriceInUSDforTWT = getRate(@token.symbol)
TWTinUSD = {value: @value * cryptorankPriceInUSDforTWT.value, decimals: @token.decimals + cryptorankPriceInUSDforTWT.decimals}
end
# If our Trading Asset (TWT) is used in BUY operation
if @from in PancakeSwapPairs && @token.contract == PancakeSwapPairs[@from].PairFirst then
# The address that initiated the TWT BUY operation
initiator = @to
# The target Pair
pair = @from
# The action
action = "BUY"
# The according to operation TWT volume update
buyVolumeTWT += @value
# The according to operation USD volume update
buyVolumeInUSD = add(buyVolumeInUSD, TWTinUSD)
# If our Trading Asset (TWT) is used in SELL operation
elseif @to in PancakeSwapPairs && @token.contract == PancakeSwapPairs[@to].PairFirst then
initiator = @from
pair = @to
action = "SELL"
sellVolumeTWT += @value
sellVolumeInUSD = add(sellVolumeInUSD, TWTinUSD)
end
let convertedBuyVolumeInUSD = {value: buyVolumeTWT * cryptorankPriceInUSDforTWT.value, decimals: @token.decimals + cryptorankPriceInUSDforTWT.decimals}
let convertedSellVolumeInUSD = {value: sellVolumeTWT * cryptorankPriceInUSDforTWT.value, decimals: @token.decimals + cryptorankPriceInUSDforTWT.decimals}
# Check that BUY or SELL happened
if action == "BUY" || action == "SELL" then
emit {
@value,
decimals: @token.decimals,
symbol: @token.symbol,
initiator,
pair: PancakeSwapPairs[pair].Pair,
action,
blockNumber: @block.number,
buyVolumeTWT,
sellVolumeTWT,
buyVolumeInUSD,
sellVolumeInUSD,
convertedBuyVolumeInUSD,
convertedSellVolumeInUSD,
cryptorankPriceInUSDforTWT
}
end
end