I've been tearing my hair out for a while now. What I have so far is cribbed from the Coinbase Pro API documentation.
The Coinbase Pro API requires four different headers, one of them being a signature that's encrypted. I'm having issues forming a valid signature. According to the Coinbase Pro API Documentation:
<?php
// Your code here!
$request_path = "/accounts";
$secret = "ZSTJxPU6g9+QLITr5U4IeKWiaoCMqs9TFnCEavdvIjQOO/TqS4ZuRirtKLKUI4UBAen0TyBEsyDmzOZQQ6SC1w==";
$ch = curl_init("https://api.pro.coinbase.com/time");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch,CURLOPT_USERAGENT,'CoinbaseProAPI');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($ch));
curl_close($ch);
$timestamp = $result->epoch;
$timestamp_rounded = intval(ceil($timestamp));
$what = $timestamp_rounded.'GET'.$request_path;
$sig = base64_encode(hash_hmac("sha256", $what, base64_decode($secret), true));
$ch = curl_init("https://api.pro.coinbase.com".$request_path) ;
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ;
curl_setopt($ch,CURLOPT_USERAGENT,'CoinbaseProAPI');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'CB-ACCESS-KEY: 513194d14d510c48fd3ba86edef54969',
'CB-ACCESS-SIGN: '.$sig,
'CB-ACCESS-PASSPHRASE: bbujnpclpsv',
'CB-ACCESS-TIMESTAMP: '.$timestamp,
'Content-Type: application/json'));
$coinbasepro_response = curl_exec($ch) ;
curl_close($ch) ;
echo $coinbasepro_response;
?>
The response I'm getting is an invalid signature. I'm stumped, and any help is appreciated.
Related
I would like to extract data from a json file. For now i want to take the value of that array but I can't really find a way to solve the problem with the second 0/1/2.
I have already tried this, but unfortunately it does not work
<?php echo $datasearch_stat[0]->statistics->0->value;?>
<?php echo $datasearch_stat[0]->statistics->[0]->value;?>
My code:
<?php
$url_stat = "....";
$curl_stat = curl_init($url_stat);
curl_setopt($curl_stat, CURLOPT_URL, $url_stat);
curl_setopt($curl_stat, CURLOPT_RETURNTRANSFER, true);
//for debug only!
curl_setopt($curl_stat, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl_stat, CURLOPT_SSL_VERIFYPEER, false);
$stat = curl_exec($curl_stat);
curl_close($curl_stat);
$datasearch_stat = json_decode($stat);
?>
Value: <?php echo $datasearch_stat[0]->statistics->0->value;?>
Json file:
Thanks in advance!
echo json_decode($stat,true)[0]["statistics"][0]["value"];
notice the "true" there, turns everything into arrays so you don't have to guess which parts are converted to objects and which are converted to arrays, they're all arrays with the 2nd true argument.
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?
I upgraded solr to the latest 7.x version and now my application seems not to remove entries via curl anymore.
Original request:
curl_request("http://".SOLR_SERVER_USERNAME.":".SOLR_SERVER_PASSWORD."#".SOLR_SERVER_HOSTNAME.":".SOLR_SERVER_PORT."/".SOLR_SERVER_PATH."/update?stream.body=<delete><query>id:".$cl_active['id']."</query></delete>&commit=true");
results in :
http://rex:8983/solr/findix/update?stream.body=%3Cdelete%3E%3Cquery%3Eid:978382%3C/query%3E%3C/delete%3E&commit=true
Response:
// 20190329102610 //
http://rex:8983/solr/findix/update?stream.body=%3Cdelete%3E%3Cquery%3Eid:978382%3C/query%3E%3C/delete%3E&commit=true
{ "error": {
"metadata": [
"error-class",
"org.apache.solr.common.SolrException",
"root-error-class",
"org.apache.solr.common.SolrException"
],
"msg": "Stream Body is disabled. See http://lucene.apache.org/solr/guide/requestdispatcher-in-solrconfig.html
for help",
"code": 400 } }
Therefore I altered it as found in this answer at SO:
update?commit=true -H "Content-Type: text/xml" --data-binary '<delete><query>id:978388</query></delete>'
like this:
curl_request("http://".SOLR_SERVER_USERNAME.":".SOLR_SERVER_PASSWORD."#".SOLR_SERVER_HOSTNAME.":".SOLR_SERVER_PORT."/".SOLR_SERVER_PATH."/update?commit=true -H 'Content-Type: text/xml' --data-binary 'id:".$cl_active['id']."'");
results in:
http://rex:8983/solr/findix/update?commit=true%20-H%20%27Content-Type:%20text/xml%27%20--data-binary%20%27%3Cdelete%3E%3Cquery%3Eid:978384%3C/delete%3E%27
Response:
// 20190329102745 //
http://rex:8983/solr/findix/update?commit=true%20-H%20%27Content-Type:%20text/xml%27%20--data-binary%20%27%3Cdelete%3E%3Cquery%3Eid:978384%3C/delete%3E%27
{ "responseHeader": {
"status": 0,
"QTime": 0 } }
What is wrong with the altered request, and how can I delete entries from the index via curl now?
Edited Question with suggestion for curl via PHP:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://".SOLR_SERVER_HOSTNAME.":".SOLR_SERVER_PORT."/".SOLR_SERVER_PATH."/update?commit=true");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml; charset=utf-8'));
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch,CURLOPT_USERPWD , "".SOLR_SERVER_USERNAME.":".SOLR_SERVER_PASSWORD."");
curl_setopt($ch, CURLOPT_POSTFIELDS, "<delete><query>id:".$cl_active['id']."</query></delete>");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
# this is your XML as given in your example above (i.e. <delete>...)
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$data = curl_exec($ch);
Response
<lst name="responseHeader"> <int name="status">400</int> <int name="QTime">0</int> </lst> <lst name="error"> <lst name="metadata">
<str name="error-class">org.apache.solr.common.SolrException</str>
<str name="root-error-class">com.ctc.wstx.exc.WstxEOFException</str> </lst> <str name="msg">Unexpected EOF in prolog at [row,col {unknown-source}]: [1,0]</str> <int name="code">400</int> </lst> </response>
The curl parameters are indented to be used with the command line version of curl. In your case you'll have to modify the curl_request method to set the appropriate headers and POST data for your request.
In PHP you can do this through curl_setopt (or with curl_setopt_array):
curl_setopt($ch, CURLOPT_URL, '... .path ...');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
# this is your XML as given in your example above (i.e. <delete>...)
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$result = curl_exec($ch);
I'm trying to output a list of items pulled from an API we use to connect to our MDM console. I have two functions, both of which work together and I can see all the data in the output of the script, however, I would like to sort this data into a .csv file using the variable names from one of the functions as the column headers. I'm new to PS and have been pulling my hair out.
I can see that the variable is an array and all the values in there, but have zero idea how to sort if or if there is a better way to grab the data I need.
#Current MDM Environment
$ev = "Q"
#Define MDM credentials to match environment from above
if($ev -eq "Q")
{
$Code = 'VbvmMGOV0Pd2lF4GurpBqnwD/R6mFmUKI6z3CKAY5tw='
$ui = 'MDMqualserver'
}
else{$Code = 'Pe8w/3jDREgse2gUu3UYZ28FHeafg0xcheu/AYwJ6PE='
$ui = 'MDMprodserver'}#>
#API Auth for MDM Console
$Auth = Get-Content -path 'C:\ProgramData\ScriptAuth\mobilityapi.txt'
$Contenttype = 'application/json'
$CurrentDate = Get-Date
$CurrentDate = $CurrentDate.ToString('MM-dd-yyyy')
$path = "C:\users\username\desktop\$currentDate.csv"
Function get_all
{
$array =#()
#Define URL
$url = "https://$ui.company.gov/api/mdm/devices/extensivesearch?
pagesize=10000"
#Define Headers
$headers = New-Object "System.Collections.Generic.Dictionary[[String],
[String]]"
$headers.Add("aw-tenant-code", $Code)
$headers.Add("Authorization", $Auth)
#Send Rest Request
try{
$response = Invoke-RestMethod -uri $url -Headers $headers}
catch{
$error = "BDevice Info Not Found"}
#Close Connection
$ServicePoint = [System.Net.ServicePointManager]::FindServicePoint($url)
$SSP = $ServicePoint.CloseConnectionGroup("")
#Parse Device Info
$data = $response.DeviceExtensiveSearchResult.Devices.DeviceDetailsExt
$data | foreach {
$serial = $_.SerialNumber
$array += $serial
}
return $array
}
Function get_devattrib
{
Param([string]$serial)
$array = #()
#Define URL
$url = "https://$ui.company.gov/api/mdm/devices?
searchby=Serialnumber&id=$serial"
#Define Headers
$headers = New-Object "System.Collections.Generic.Dictionary[[String],
[String]]"
$headers.Add("aw-tenant-code", $Code)
$headers.Add("Authorization", $Auth)
$headers.Add("Content-Type", $Contenttype)
#Send Rest Request
try{
$response = Invoke-RestMethod -uri $url -Headers $headers}
catch{
return $false}
#Close Connection
$ServicePoint = [System.Net.ServicePointManager]::FindServicePoint($url)
$ServicePoint.CloseConnectionGroup("")
#Parse Device Info (#removed .Device from $data = $response.Device)
$data = $response
$data | foreach {
$ownership = $_.Ownership
$friendlyname = $_.DeviceFriendlyName
$platform = $_.Platform
$model = $_.Model
$snumber = $_.AssetNumber
$username = $_.UserName
$mac = $_.MacAddress
$phone = $_.PhoneNumber
$lastseen = $_.LastSeen
$enrollstatus = $_.EnrollmentStatus
$compliance = $_.ComplianceStatus
return [datetime]$lastseen, $ownership, $friendlyname, $platform, $model,
$snumber, $serial, $username, $mac, $phone, $enrollstatus, $compliance
}
}
$devices = #()
$getdevices = #()
$devices = get_all
foreach ($device in $devices){
$getdevices += get_devattrib $device
}
$getdevices
The output of the data looks like this for each device in our console (I have made the info generic to hide company data):
True
Wednesday, September 5, 2018 8:33:21 PM Corporate Owned username - assetnumber Apple iPad Pro with Wi-Fi + Cellular (128 GB Space Gray) asset number serial nubmer username mac address phonenumber Enrolled NonCompliant
A. I don't understand why I get "true" at the beginning of the output for each device in the console and the space afterwards (which seems to come with the [datetime])
B. I don't understand how to place all this data in a .csv file. I do have a path defined before the functions and know how to use export-csv, but the data that it sends to the file appears as just #TYPE System.Boolean so I'm assuming there is something wrong with my last variable. Whew.
You can sort with Sort-Object.
$ArrayOfStrings = 's', 't', 'a', 'c', 'k'
$ArrayOfStrings | Sort-Object
I need to implement a web app that consists in publishing events with the option of send notifications to subscribed people. How can I use the codename one libraries from a Web App?
Another question: When a cell phone receive the notification, can the application be opened in a specific window, in this case, the window which contain the event description?
Thank you in advance.
If your web app server is running php, you can use CURL to send push notifications to devices. You can easily do the same with other languages. See below sample php code I used.
Shai mentioned recently that you can include some hidden payload in your push message. You can add some variables to this data which you'll check and use to open the necessary form.
PHP sample code:
$cloudServerURL = "https://push.codenameone.com/push/push";
$token = "Your_Developer_token"; //Can be found under account tab of Dashboard
$auth = "Google_Push_Key";
$certPassword = "Your_Certificate_Password";
$cert = "https://www.dropbox.com/path_to_your_iOS_cert/MyAppDevPush.p12?dl=1"; //Test
//Note the 'dl=1', this will download the certificate, instead of opening it.
//$cert = "https://www.dropbox.com/path_to_your_iOS_cert/MyAppProPush.p12?dl=1"; //Live
$production = "false"; //Test
//$production = "True"; //Live
$burl = "";
$bbAppId = "";
$bbPass = "";
$bbPort = "";
$device = 'device_key';
$type = "3"; //Or other types like (2, 101) as required
$body = "Hello world";
$arguments = 'token=' . $token . '&device=' . $device . '&type=' . $type . '&auth=' . $auth . '&certPassword=' . $certPassword . '&cert=' . $cert . '&body=' . $body . '&burl=' . $burl . '&bbAppId=' . $bbAppId . '&bbPass=' . $bbPass . '&bbPort=' . $bbPort . '&production=' . $production;
$ch = curl_init($cloudServerURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $arguments);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
$response = unserialize(curl_multi_getcontent($ch));));
curl_close($ch);