Coinbase API getBalance ignoring ETC currency - coinbase-api

The PHP uses the Coinbase API to get the current balance and list what currencies the account has money in. It has been used for a few weeks now, but since swapping one currency into ETC (Ethereum Classic), the balance ignores this currency. It works for all other currencies I have tried, so what is special about ETC that Coinbase is not returing anything via the API. The coinbase website portfolio does report the ETC balance correctly, so it's definitely a API issue.
<?php
include 'cfg.php'; // Contains API key
require_once ('vendor/autoload.php'); // Loads the API libraries
use Coinbase\Wallet\Client as Client;
use Coinbase\Wallet\Configuration as Configuration;
use Coinbase\Wallet\Enum\Param;
use Coinbase\Wallet\Resource\Transaction;
$configuration = Configuration::apiKey($cbase_API_Key, $cbase_API_Secret);
$client = Client::create($configuration);
$stime = $client->getTime();
echo '<h2> Server Time ' . $stime['iso'] . '</h2>';
$balance = 0.00;
$accounts = $client->getAccounts(); // Get the account(s)
echo '<table>';
foreach ( $accounts as $acct )
{
$amt = $acct->getBalance()->getAmount() ;
echo '<tr>';
echo '<td>' . $acct->getCurrency() . '</td>';
echo '<td>' . $acct->getName() . '</td>';
echo '<td>' . $acct->getBalance()->getAmount() . '</td>';
echo '<td>' . $acct->getNativeBalance()->getAmount() . '</td>';
echo '</tr>';
$balance = $balance + $acct->getNativeBalance()->getAmount();
}
echo '<table>';
echo '<h2> Total Balance: ' . $balance . '</h2>';
?>

The issue came down to pagination:
The fix therefore was to set the pagination limit to 100 (max allowed).
The default is 24, hence why the returned list was incomplete.
$accounts = $client->getAccounts(['limit' => 100]);

Related

Coinbase PHP API Historic prices in GBP

I collect crypto prices and save them to a database every minute.
There are times every now and then when my system is down, which creates gaps in my prices data.
I found out how to get Historic Prices between two time stamps. e.g:
https://api.pro.coinbase.com/products/ALGO-GBP/candles?start=2021-05-13T02:20:06.0Z&end=2021-05-13T09:44:12.0Z&granularity=300
When the system comes back up I have a PHP script that checks for gaps and then constructs the above URL call to get the prices.
This works well for most of the crypto, but for a few I get no data being returned, e.g. ATOM-GBP.
After some investigation I found it is because for these I must specify ATOM-USD, or ATOM-BTC.
The problem here is first knowing which one to use, and secondly, how to convert the returned price to GBP at the timestamp concerned.
Here is my snippet code:
<?php
date_default_timezone_set('Europe/London'); // YOUR timezone, of the server
ini_set('memory_limit', '256M');
?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css?v=<?=time();?>">
</head>
<body>
<H1> Missing Prices <?= date("Y-m-d H:i:s") ?> </H1>
<p>
<?php
error_reporting(E_ALL);
include 'cfg.php';
require_once ('vendor/autoload.php');
include ('db_conn.php');
use Coinbase\Wallet\Client as Client;
use Coinbase\Wallet\Configuration as Configuration;
$configuration = Configuration::apiKey($cbase_API_Key, $cbase_API_Secret);
$client = Client::create($configuration);
// List prices from local database
$price_sql = "
SELECT p1.ccode,
CONVERT_TZ(p1.tstamp,'Europe/London','UTC') ts1,
UNIX_TIMESTAMP(CONVERT_TZ(p1.tstamp,'Europe/London','UTC')) ut
FROM prices p1
WHERE p1.tstamp BETWEEN (NOW() - INTERVAL 5 DAY ) AND (NOW() - INTERVAL 3 DAY )
ORDER BY 1, 2
";
$stmt = $dbh->prepare($price_sql);
$stmt->execute();
$result = $stmt->get_result();
$data = $result->fetch_all(MYSQLI_ASSOC);
$num_rows = $result -> num_rows;
$prev_ut = -1;
$prev_ts = "";
$prev_curr = "";
$c = 0;
foreach ($data as $row)
{
if ( $prev_ut == -1 )
{
$prev_ut = $row['ut'];
$prev_ts = $row['ts1'];
$prev_curr = $row['ccode'];
}
$ut_diff = $row['ut'] - $prev_ut;
if ( $prev_curr != $row['ccode'] )
{
$ut_diff = 0;
}
// If the gap between current and previous row is over 5 minutes then we have a gap
if ( $ut_diff > 300 )
{
echo '<H2> Missing data for ' . $row['ccode'] . " between " .
$row['ts1'] . " and " . $prev_ts . " diff " . $ut_diff . "</H2>";
// Build up URL
$nxt_ts = DateTime::createFromFormat('Y-m-d H:i:s', $prev_ts );
$pts = $nxt_ts->format('Y-m-d H:i:s');
$strt = str_replace(' ', 'T', $prev_ts);
$end = str_replace(' ', 'T', $row['ts1']);
$url = "https://api.pro.coinbase.com/products/" . $row['ccode'] . "-GBP/candles?start=" . $strt . ".0Z&end=" . $end . ".0Z&granularity=300";
echo '<h3> ' . $url . '</h3>';
echo '<table border="1">';
echo '<tr>';
echo '<th> No</th>';
echo '<th> Currency </th>';
echo '<th> Time </th>';
echo '<th> Low </th>';
echo '<th> High </th>';
echo '<th> Open </th>';
echo '<th> Close </th>';
echo '<th> Volume </th>';
echo '</tr>';
// Use curl to get the data
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$prices_json = json_decode(curl_exec($ch), true);
foreach($prices_json as $price )
{
$c++;
$utime = gmdate( 'r', $price[0]);
$low = $price[1];
$high = $price[2];
$open = $price[3];
$close = $price[4];
$volume = $price[5];
echo '<tr>';
echo '<td>' . $c . '</td>';
echo '<td>' . $row['ccode'] . '</td>';
echo '<td>' . $utime . '</td>';
echo '<td>' . $low . '</td>';
echo '<td>' . $high . '</td>';
echo '<td>' . $open . '</td>';
echo '<td>' . $close . '</td>';
echo '<td>' . $volume . '</td>';
echo '</tr>';
}
}
echo '</table>';
$prev_ut = $row['ut'];
$prev_ts = $row['ts1'];
$prev_curr = $row['ccode'];
}
?>
Results snippet:
Missing data for ATOM between 2021-05-13 09:44:12 and 2021-05-13 02:20:06 diff 26646
https://api.pro.coinbase.com/products/ATOM-GBP/candles?start=2021-05-13T02:20:06.0Z&end=2021-05-13T09:44:12.0Z&granularity=300
Warning: gmdate() expects parameter 2 to be integer, string given in fillpricegaps.php on line 172
No Currency Time Low High Open Close Volume
409 ATOM o t F o u
Missing data for BAL between 2021-05-13 09:44:15 and 2021-05-13 02:20:10 diff 26645
https://api.pro.coinbase.com/products/BAL-GBP/candles?start=2021-05-13T02:20:10.0Z&end=2021-05-13T09:44:15.0Z&granularity=300
Warning: gmdate() expects parameter 2 to be integer, string given in fillpricegaps.php on line 172
No Currency Time Low High Open Close Volume
410 BAL o t F o u
Missing data for BAND between 2021-05-13 09:44:13 and 2021-05-13 02:20:08 diff 26645
https://api.pro.coinbase.com/products/BAND-GBP/candles?start=2021-05-13T02:20:08.0Z&end=2021-05-13T09:44:13.0Z&granularity=300
No Currency Time Low High Open Close Volume
411 BAND Thu, 13 May 2021 09:40:00 +0000 10.4942 10.5993 10.5939 10.5248 1080.08
412 BAND Thu, 13 May 2021 09:35:00 +0000 10.6262 10.7359 10.717 10.627 185.25
413 BAND Thu, 13 May 2021 09:30:00 +0000 10.6525 10.8151 10.6525 10.7991 338.32
414 BAND Thu, 13 May 2021 09:25:00 +0000 10.641 10.7716 10.7521 10.641 134.54
Can you not grab the BTCUSD and also BTCGBP to find the conversion rate between USD and GBP?

Joomla 3: selecting multiple custom user fields into one html table

Forgive me - pretty much a Joomla/SQL rookie and trying to navigate through some tasks I trying to help my local home owners association with.
I'm looking for a way to build my own user list containing multiple custom user fields. My current query gives me multiple records for each user because each user is linked to multiple fields in the "__fields_values" table. I need only ONE record for each user and each custom field as a seperate value in this row.
A simple group clause doesn't seem to cut it.
Nevermind the actual table html, that's just for testing right now.
Hope someone can help me see the light :)
Now I get:
username1|field1|<blank>|email
username1|field2|<blank>|email
My table should look like:
username1|field1|field2|email
My current query and output:
$query = $db->getQuery(true);
$query
->select('*')
->from($db->quoteName('#__users', 'u'))
->join('INNER', $db->quoteName('#__user_usergroup_map', 'm') . ' ON (' . $db->quoteName('u.id') . ' = ' . $db->quoteName('m.user_id') . ')')
->join('INNER', $db->quoteName('#__fields_values', 'f') . ' ON (' . $db->quoteName('u.id') . ' = ' . $db->quoteName('f.item_id') . ')')
->where($db->quoteName('group_id') . ' = ' . $group_id)
->order($db->quoteName('u.username') . ' ASC')
$db->setQuery($query);
$users = $db->loadObjectList();
And then output to this table:
<table style="width:100%">
<tr style="border-bottom:1pt solid black;text-align: left;">
<th>Name</th>
<th>CustomField1</th>
<th>CustomField2</th>
<th>Email</th>
</tr>
<?php
foreach($users AS $user)
{
?>
<tr>
<td><?php;
echo $user->name;
?></td>
</td>
<td><?php;
echo $user->value;
?></td>
<td><?php;
echo $user->NEED ANOTHER VALUE HERE;
?></td>
<td><?php;
echo $user->email;
}?>
</table>
Probably You can do something like this to concatenate the result. If you are not getting the exact result you can just play with the code for what result you want. Your fields will be in the field array.
I have used CONCAT and GROUP_CONCAT. And you can have a look at it here https://www.w3resource.com/mysql/aggregate-functions-and-grouping/aggregate-functions-and-grouping-group_concat.php
$query = $db->getQuery(true)
->select(
array(
'*',
"CONCAT('[',GROUP_CONCAT(".$db->quoteName('f.value')."),']') field"
)
)
->from($db->quoteName('#__users', 'u'))
->leftJoin($db->quoteName('#__user_usergroup_map', 'm') . ' ON (' . $db->quoteName('u.id') . ' = ' . $db->quoteName('m.user_id'). ')')
->leftJoin($db->quoteName('#__fields_values', 'f') . ' ON (' . $db->quoteName('u.id') . ' = ' . $db->quoteName('f.item_id') . ')')
->where($db->quoteName('group_id') . ' = ' . $group_id);
$db->setQuery($query);
$users = $db->loadObjectList();
This will result in a singly array which you can do a var_dump() and check for yourself.

Wordpress admin - Where in database is it set?

I'm looking to grab admin user emails to use within a contact form. I have 2 admins that I've assigned. I'd like to grab them from the database. Where is/what is the designation point that I can use when I make the sql statment?
You can do the following
global $wpdb;
//comma separated list
$admins=$wpdb->get_var('select group_concat(`user_email`) as `admin_emails` from `' . $wpdb->prefix . 'users` as `users` inner join `' . $wpdb->prefix . 'usermeta` as `usermeta` on `usermeta`.`user_id`=`users`.`ID` where `meta_key`=\'wp_user_level\' and `meta_value` in (8,9,10);');
//array of associated arrays
$admins=$wpdb->get_results('select `user_email` from `' . $wpdb->prefix . 'users` as `users` inner join `' . $wpdb->prefix . 'usermeta` as `usermeta` on `usermeta`.`user_id`=`users`.`ID` where `meta_key`=\'wp_user_level\' and `meta_value` in (8,9,10);', ARRAY_A);
<?php $user_info = get_userdata(1);
echo 'Username: ' . $user_info->user_login . "\n";
echo 'User roles: ' . implode(', ', $user_info->roles) . "\n";
echo 'User ID: ' . $user_info->ID . "\n";
?>
You can pass the User id herer.....
The first thing to do is to create the function. To do so, paste the following code in your functions.php file:
function getUsersByRole($role) {
$wp_user_search = new WP_User_Search($usersearch, $userspage, $role);
return $wp_user_search->get_results();
}
Once done, you can call the function this way:
$editors = getUsersByRole('Administrator');
foreach($editors as $editor){
//$editor now holds the user ID of an editor
}

Horizontal calendar using PHP

You can see what I am trying to make here http://perthurbanist.com/website/calendarloader.php. Basically it is a horizontal calendar and you will use arrows to move. What I want to do is have the code display all the months horizontally along with all the days (starting from the current month and day). I know how to get the current day using the date function but I don't know how to make the calendar start at that date. I also want it to load lots of months (maybe 2-3 years worth). How do I do those two things.
<?php
$showday = date("j");
$displaymonth = date("M");
$showmonth = date("n");
$showyear = date("Y");
$day_count = cal_days_in_month(CAL_GREGORIAN, $showmonth, $showyear);
echo '<ul class="calendarnavigation">';
echo '<li class="month">' . $displaymonth . '</li>';
for($i=1; $i<= $day_count; $i++) {
echo '<li>' . $i . '</li>';
}
echo '</div>';
?>
If you know (or are able to calculate how far ahead you want to go in days you could try this:
for($i=0; $i<$numberOfDays; $i++)
{
$timestamp=mktime(0,0,0,date("m"),date("d")+$i,date("Y"));
$day=date("d", $timestamp);
$month=date("m", $timestamp);
$year=date("Y", $timestamp);
...Your display stuff here...
}
On each iteration of the loop the $timestamp will advance one day and using it in your date functions will give you the information about the date that you need to create your display.
Maybe in your case you can use
echo '<ul class="calendarnavigation">';
for($i=0; $i<$numberOfDays; $i++)
{
$timestamp=mktime(0,0,0,date("m"),date("d")+$i,date("Y"));
$showday=date("j", $timestamp);
$displaymonth=date("M", $timestamp);
$showmonth=date("n", $timestamp);
$showyear=date("Y", $timestamp);
if($showday=="1")
{
echo '<li>'.$displaymonth.'</li>';
}
echo '<li>'.$showday.'</li>';
}
echo '</ul>';

How to send email after registering

After that someone registers in a site, a mail is usually sent to his mail account. But to generate this link or what info can be placed in this link so that it can be used to activate the user account??
you can place any thing which can identify a valid user
1- A Hash Value
2- An Encrypted String
3- A Guid
and when user clicks on the link , you can validate the value.
Check this part of code:
Generate code and e-mail:
/* if $acces = 0 everything is perfect so the system send a confirmation mail */
if($acces == 0)
{
print("<br>A mail has been send to " . $mail . "<br><br>") ;
/* prepare the vars */
$activ = $user . $pass ;
$code = md5($activ) ;
/* to how send to mail */
$to = $mail ;
/* prepare the subject */
$subject = "You need to confirm you registration to " . $_SERVER['HTTP_HOST'] ;
/* start writing the message */
$message = "Hello " . $user . ",\r\n\r\n" ;
$message .= "Thank you for registering at " . $_SERVER['HTTP_HOST'] . " Your account is created and must be activated before you can use it.\r\n" ;
$message .= "To activate the account click on the following link or copy-paste it in your browser :\r\n\r\n" ;
$message .= "http://" . $_SERVER['HTTP_HOST'] . "/~carron/registration/register_send.php?user=" . $user . "&activation=" . $code . "\r\n\r\n" ;
$message .= "After activation you may login to http://" . $_SERVER['HTTP_HOST'] . " using the following username and password:\r\n\r\n" ;
$message .= "Username - " . $user . "\r\nPassword - " . $pass . "\r\n" ;
/* To send HTML mail, you can set the Content-type header. */
$headers = "MIME-Version: 1.0";
$headers .= "Content-type: text/html; charset=iso-8859-1";
/* set up additional headers */
$headers .= "To: " . $to . "<br>\n" ;
$headers .= "From: " . $from . $addmail ;
/* writing data in the base */
$query = "INSERT INTO registration (user, pass, activ, mail) VALUES ('$user', '$pass', '$code', '$mail') ;" ;
$result = mysql_query($query, $db);
if ($result == false)
die("Failed " . $query);
else
{
/* everything went well so we can mail it now */
mail($to, $subject, $message, $headers);
}
}
Check activation:
/* controle if the validation link is right */
$x = 0 ;
$query = "SELECT user, pass, activ, mail FROM registration WHERE user = '" . $username . "';" ;
$result = mysql_query($query, $db);
if ($result == false) die("Failed " . $query);
while ($fields = mysql_fetch_row($result))
{
for ($i=0, $max=sizeof($fields) ; $i < $max ; $i++)
{
$tmp[$i] = $fields[$i] ;
}
/* the activation link is right so we can update
the datas in the data base */
if($activation == $tmp[2] AND $username == $tmp[0])
{
$x = 1 ;
$query2 = "UPDATE registration SET activated = '1' WHERE user = '" . $username . "' AND activ = '" . $activation . "' ;" ;
$result2 = mysql_query($query2, $db);
if ($result2 == false)
die("Failed " . $query2);
}
else
$x = -1 ;
}
/* give a confirmation message to the user */
if($x == 1)
print($username . " your activation has been done perfectly<br> Thank you...") ;
else
print($username . " your activation has not been done corectly<br> Please try again later...") ;
Script from PHPclasses.org
The idea is to have a link that only the recipient of the email knows. So when that link is visited on your site, you know that someone has read the email you sent and clicked on the link and so you can presume that the person who registered and the person who read the email are the same.
As such, you just need a link that can't be easily guessed. Pick something random (and record it in the user's profile) or hash the user name + a seed, or something.
When user registered, you can use uniqid() to create an activate code and stored in database. Then in mail, give a link like: http://....../activate.php?code=[uniqid()]
In activate.php, you can read activate code from database and check it.

Resources