Previous part 5: Notifying price quotes on your phone
The Bitcoin Cash SDK for Tasker
As we saw in part 1, the main goal for all the interfaces and implementations we've been developing is to offer a common software development kit for tasker users to automatize their BCH-related routines and develop new ones.
The configure call
The goal of this call is to set the basic information the SDK needs to work on.
entry:
( . . . )
function_configure:
VariableSet(Name="%parameters", To="%par2");
VariableSplit(Name="%parameters", Splitter=";");
VariableSet(Name="%ADDRESSES", To="%parameters1");
VariableSet(Name="%CACHED_ADDRESSES", To="%ADDRESSES");
VariableSet(Name="%API_KEY", To="%parameters2");
VariableSet(Name="%CURRENCY", To="%parameters3");
Return(Value="SUCCESS", Stop="On");
function_loadBalance:
( . . . )
Step by step:
Split the three semicolon-separated parameters into the
%parameters
ArraySet the constants
%ADDRESSES
,%API_KEY
and%CURRENCY
Set the
%CACHED_ADDRESSES
constant with the%ADDRESSES
value (we'll explain this later)Return when everything is done
Loading the balance data
The goal is to load and return the current balance with a simple call.
entry:
( . . . )
function_configure:
( . . . )
function_loadBalance:
PerformTask(Name="BlockChairBlockExplorerAPI", Parameter1="function_load", Parameter2="%CACHED_ADDRESSES;%API_KEY", ReturnValue="%retval");
Return(Value="ERROR At TaskerBchSdk : %retval", If="%retval !~ SUCCESS");
PerformTask(Name="BlockChairBlockExplorerAPI", Parameter1="function_getTotalBalance", ReturnValue="%retval");
Return(Value="%retval", Stop="On");
function_loadCurrencyValue:
( . . . )
Step by step:
Call the load function with the configured parameters
Check if there was an error and stop the task if so
Retrieve the total balance value
Return that value to the caller
Load preferred currency quote
The goal is to load the BCH - CURRENCY exchange ratio and return it to the caller.
entry:
( . . . )
function_configure:
( . . . )
function_loadBalance:
( . . . )
function_loadCurrencyValue:
PerformTask(Name="CoinGeckoExchangeAPI", Parameter1="function_load", ReturnValue="%retval");
Return(Value="ERROR At TaskerBchSdk : %retval", If="%retval !~ SUCCESS");
PerformTask(Name="CoinGeckoExchangeAPI", Parameter1="function_getTotalBalance", Parameter2="%CURRENCY", ReturnValue="%retval");
Return(Value="%retval", Stop="On");
function_computeCache:
( . . . )
Step by step:
Call the load function with the configured parameters
Check if there was an error and stop the task if so
Retrieve the current currency exchange value
Return that value to the caller
Computing the cache
Our Addresses list can grow to be really long if we use many BIP39 wallets, usually having tons of addresses that do not contain any UTXO at all, we already created a function at the Block Explorer interface that gives us a list of addresses with funds and we are going to use it to update the %CACHED_ADDRESSES
variables, effectively reducing the querying cost.
entry:
( . . . )
function_configure:
( . . . )
function_loadBalance:
( . . . )
function_loadCurrencyValue:
( . . . )
function_computeCache:
PerformTask(Name="BlockChairBlockExplorerAPI", Parameter1="function_load", Parameter2="%ADDRESSES;%API_KEY", ReturnValue="%retval");
Return(Value="ERROR At TaskerBchSdk : %retval", If="%retval !~ SUCCESS");
PerformTask(Name="BlockChairBlockExplorerAPI", Parameter1="function_getFundedAddresses", ReturnValue="%CACHED_ADDRESSES");
Return(Value="SUCCESS", Stop="On");
function_checkCache:
( . . . )
Step by step:
We load all of our addresses (
%ADDRESSES
) on the block explorerReturn if there's an error
Compute the funded addresses and store it (
%CACHED_ADDRESSES
)Return
Checking if it's necessary to compute the cache
There are several ways where the number of funded addresses could be rendered obsolete:
When a transaction is performed on an unused address the cache won't catch it, as it's happening on one of the addresses that we are ignoring
When one address that had funds spends all of them, going to zero balance
To solve the first one we can schedule a periodic call to computeCache
and to solve the second, one could be tempted to just remove the address, that would be ok in all cases where spending all funds implies sending them to another person, but actually the most common case is to have some change as a leftover and sending it to another address (usually dedicated for receiving change) in our wallet, that's why we would be checking, with the following function, if one of our addresses was depleted.
entry:
( . . . )
function_configure:
( . . . )
function_loadBalance:
( . . . )
function_loadCurrencyValue:
( . . . )
function_computeCache:
( . . . )
function_checkCache:
VariableSet(Name="%current_cache", To="%CACHED_ADDRESSES");
PerformTask(Name="BlockChairBlockExplorerAPI", Parameter1="function_getFundedAddresses", ReturnValue="%latest_cache");
VariableSplit(Name="%current_cache", Splitter=",");
VariableSplit(Name="%latest_cache", Splitter=",");
Return(Value="TRUE", Stop="On", If="%current_cache(#) eq %latest_cache(#)");
Return(Value="FALSE", Stop="On");
function_notifyChanges
( . . . )
Step by step:
Copy the current cache and the latest list of funded addresses to local variables (
%current_cache
and%latest_cache
respectively)Split both variables by comma
Return TRUE if both arrays have the same length
Return FALSE otherwise
Notifying function
The goal is to get both balance and value and calling the notification service we made at part 5. The calling format will be %balance;%value
entry:
( . . . )
function_configure:
( . . . )
function_loadBalance:
( . . . )
function_loadCurrencyValue:
( . . . )
function_computeCache:
( . . . )
function_checkCache:
( . . . )
function_notifyChanges
VariableSet(Name="%params", To="%par2");
VariableSplit(Name="%params", Splitter=";");
PerformTask(Name="PushNotificationGui", Parameter1="function_updateValue", Parameter2="%params2");
PerformTask(Name="PushNotificationGui", Parameter1="function_updateBalance", Parameter2="%params1");
PerformTask(Name="PushNotificationGui", Parameter1="function_notify");
Return(Value="SUCCESS", Stop="On");
Step by step:
copy the parameters and split them by ";"
Update the value an then the balance at the notification object, respectively
notify the changes to the user
Return
Use case example
Sdk_configure
This code will prompt you to input the addresses you are going to use, the currency and the API key if applicable. This is meant to be used whenever you want to change one of these settings, but at least once before start using this SDK.
VariableQuery(Title="input addresses", Variable="%addresses");
VariableQuery(Title="input api key (if any)", Variable="%api_key");
VariableQuery(Title="input currency", Variable="%currency", Default="usd");
PerformTask(Name="TaskerBchSdk", Parameter1="function_configure", Parameter2="%addresses;%api_key;%currency");
Sdk_routine
This code will load the balance, load the currency quotes, notify the changes and update the cache if necessary, this code is meant to be used as a periodic task (i.e: every thirty minutes)
PerformTask(Name="TaskerBchSdk", Parameter1="function_loadBalance", ReturnValue="%balance");
Popup(Title="ERROR", Text="%balance", If="%balance ~ ERROR");
PerformTask(Name="TaskerBchSdk", Parameter1="function_loadCurrencyValue", ReturnValue="%value");
Popup(Title="ERROR", Text="%value", If="%value ~ ERROR");
PerformTask(Name="TaskerBchSdk", Parameter1="function_notify", Parameter2="%balance;%value");
PerformTask(Name="TaskerBchSdk", Parameter1="function_checkCache", ReturnValue="%retval");
If("%retval ~ FALSE");
PerformTask(Name="TaskerBchSdk", Parameter1="function_computeCache", ReturnValue="%retval");
Popup(Title="ERROR", Text="%retval", If="%retval ~ ERROR");
EndIf();
Sdk_cache
Finally, This code will refresh the cache, this code is meant to be used once a day, to avoid orphan addresses with funds.
PerformTask(Name="TaskerBchSdk", Parameter1="function_computeCache", ReturnValue="%retval");
Popup(Title="ERROR", Text="%retval", If="%retval ~ ERROR");
"Dude, I pass on implementing this here... Where can I download it?"
You can access the Sdk on this link. (You need to have tasker installed) or download the import XML directly from Github.
Special thanks to Blockchair.com for providing the API key
Don't forget to subscribe, feedback will be appreciated!
Expect future updates! Requests are accepted at comments.
Really very nice