how to send and receive tokens via Solana JSONRPC - php

there's the following ETH JSONRPC implementation to transfer tokens, which can be utilised via curl in PHP and I would like to do EXACTLY the same but on the Solana Blockchain - which supports it's own JSONRPC implementation
var whatever= {};
whatever.jsonrpc="2.0";
whatever.id=1;
whatever.method="eth_sendTransaction";
whatever.params= [];
whatever.params[0].from="0x52f273a06a420453aa5b33c4f175395c9a1fddd8";
whatever.params[0].to=data.ethAddress;
whatever.params[0].value=1e18;
whatever.params[0].currency="xxx";
source on stack overflow for the above code is here
as the Solana Documentation mentions only sendTrasactions here are my two questions:
how to implement the above example using Solana (see below our curl implementation of the Solana JSONRPC to get a user's current token amount in php i.e. "getTokenAmount")
where do I get the fully-signed Transaction as an encoded string which is a parameter for the "sendTransaction"*
*I assume the fully-signed Transaction is issued once the transfer is made, no?
----- example of our implementation as mentioned above (for those who might be interested in it -----
public function getTokenAmount($wallet_address, $token_address)
{
$data = array(
"jsonrpc" => "2.0",
"id" => 1,
"method" => "getTokenAccountsByOwner",
"params" => array(
0 => $wallet_address,
1 => array(
"mint" => $token_address
),
2 => array(
"encoding" => "jsonParsed"
)
)
);
$data = json_encode($customer);
$response = $this->initCurl($data);
return $response->result->value[0]->account->data->parsed->info->tokenAmount->uiAmount;
}
private function initCurl($data)
{
$ch = #curl_init();
#curl_setopt($ch, CURLOPT_POST, true);
#curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
#curl_setopt($ch, CURLOPT_URL, $this->_endpoint);
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
#curl_setopt($ch, CURLOPT_HTTPHEADER, array( "accept: application/json", "content-type: application/json"));
$response = json_decode(#curl_exec($ch));
$err = #curl_error($ch);
curl_close($ch);
// TODO: ERROR HANDLING
if ($err) {
return false; //"cURL Error #:" . $err;
}
return $response;
}

The answers to 1 and 2 are very similar.
In order to send a transaction, you must create a base64 or base58 encoded string with all of the transaction data, which includes accounts, data, and any other flags needed. After that, you must sign the transaction with a ed25519 key, and provide that whole string as the transaction.
You can build this yourself by following how it's done for JS:
system instruction, specifically transfer: https://github.com/solana-labs/solana/blob/005592998dd107b3d54d9203babe24da681834f5/web3.js/src/system-program.ts#L676
transaction, specifically adding instructions, compiling the message, and signing: https://github.com/solana-labs/solana/blob/005592998dd107b3d54d9203babe24da681834f5/web3.js/src/transaction.ts#L205
Your better bet, however, would be to reuse an existing library which has already done a lot of this work for you. For example, https://github.com/tighten/solana-php-sdk#transactions provides an easy API to do exactly what you're looking for.

Related

How do I send info to this API using cURL and PUT?

I am working with an API that is documented here: https://cutt.ly/BygHsPV
The documentation is a bit thin, but I am trying to understand it the best I can. There will not be a developer from the creator of the API available before the middle of next week, and I was hoping to get stuff done before that.
Basically what I am trying to do is update the consent of the customer. As far as I can understand from the documentation under API -> Customer I need to send info through PUT to /customers/{customerId}. That object has an array called "communicationChoices".
Going into Objects -> CustomerUpdate I find "communicationChoices" which is specified as "Type: list of CommunicationChoiceRequest". That object looks like this:
{
"choice": true,
"typeCode": ""
}
Doing my best do understand this, I have made this function:
function update_customer_consent() {
global $userPhone, $username, $password;
// Use phone number to get correct user
$url = 'https://apiurlredacted.com/api/v1/customers/' . $userPhone .'?customeridtype=MOBILE';
// Initiate cURL.
$ch = curl_init( $url );
// Specify the username and password using the CURLOPT_USERPWD option.
curl_setopt( $ch, CURLOPT_USERPWD, $username . ":" . $password );
// Tell cURL to return the output as a string instead
// of dumping it to the browser.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
// Data to send
$data = [
"communicationChoices" => [
"communicationChoiceRequest" => [
"choice" => true,
"typeCode" => "SMS"
]
]
];
$json_payload = json_encode($data);
print_r($json_payload);
// Set other options
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($json_payload)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_payload);
// Execute the cURL request
$response = curl_exec($ch);
// Check for errors.
if( curl_errno( $ch ) ) :
// If an error occured, throw an Exception.
throw new Exception( curl_error( $ch ) );
endif;
if (!$response)
{
return false;
} else {
// Decode JSON
$obj = json_decode( $response );
}
print_r($response);
}
I understand that this is very hard to debug without knowing what is going on within the API and with limited documentation, but I figured asking here was worth a shot anyway.
Basically, $json_payload seems to be a perfectly fine JSON object. The response from the API however, is an error code that means unknown error. So I must be doing something wrong. Maybe someone has more experience with APIs and such documentation and can see what I should really be sending and how.
Any help or guidance will be highly appreciated!
before you test your code, you can use the form provided on the API Documentation.
when you navigate to API > Customers > /customers/{customerId} (GET), you will see a form on the right side of the page (scroll up). you need to provide the required values on the form then hit Submit button. you will surely get a valid data for communicationChoices based on the result from the Response Text section below the Submit button.
now, follow the data structure of communicationChoices object that you get from the result and try the same on API > Customers > /customers/{customerId} (PUT) form.
using the API forms, you may be able to instantly see a success or error from your input (data structure), then translate it to your code.

Wink API v2 Hello World in PHP

Wink API is currently on version 2.
My Question: How can you do a simple "Hello World" with the Wink API V2 via PHP?
Notes:
Wink uses PubNub for subscriptions (devices have an event)
Uses OAuth2 standard
Website/Login is often "hokey": (& will error when you login: "Authentication failed!")
Login here: https://developer.wink.com & use Google account (or whatever)
Then change URL to this: https://developer.wink.com/clients
Sometimes you have to do this a couple times!!
You will need to request an Application API key in order to use the API. I followed up with an email to get it approved swiftly.
Once you are approved, you'll get: Client ID, Client Secret, & URLs to assist
API URL: https://api.wink.com/...
Email support: support#wink.zendesk.com (Get Application API key, etc)
OAuth 2:
Wink indicates to use "Authorization Code Grant Type"
Dox & Example: https://developer.byu.edu/docs/consume-api/use-api/choose-grant-type
Related Links:
Wink API: https://winkapiv2.docs.apiary.io/#
Stackoverflow related questions:
How to use Wink API V2 from a non-web app
Issues with Pubnub + Wink Hub and sensors
Wink API Subscriptions Stop Sending Overnight
https://community.home-assistant.io/t/wink-access-token-issue/52197/15
Github Example: https://github.com/cbulock/php-wink (This was last updated 3 years ago; might be on previous API ver)
Information regarding this is extremely limited, so I'll answer my own question hoping to help others. (It took a long time since there wasn't any good info out there.) This example has a user interface (Login required by Wink). I'm hoping someone can post a non-user-interface version (for background scripting, etc).
This will give you raw json output, for you to do with as you wish. This single php page will initially load, take you to Wink's login (you need an account with your devices if this wasn't obvious), after logging it, it will take you back to this same page with a code, call for a token, then use that token to get the device resources.
Create: //[YourServer]/wink_helloworld.php on your http/php server.
wink_helloworld.php:
//Make sure to add this exact URL to your Wink Developer Portal! (https://developer.wink.com/clients)
$redirect_uri = "http://[YourServer]/wink_helloworld.php";
// This is from Wink Developer Portal
$client_id = "abcdefg";
$wink_oauth_url = "https://api.wink.com/oauth2/token";
$client_secret = "hijklmnop";
$devices_url = "https://api.wink.com/users/me/wink_devices";
//need to create a state variable, like a session id. should actually be random tho!!
$randomstring="xyzABC123";
$state = base64_encode($randomstring);
/*_____________________________________________________________________________________________________________________________________ */
echo "<h2>Wink Hello World - Show Devices</h2>";
//If we don't have a code, then send user to login page
if($_GET['code'] == null | $_GET['code'] == ""){
echo "<a href='https://api.wink.com/oauth2/authorize?response_type=code&client_id=".$client_id."&redirect_uri=$redirect_uri&state=".$state."'>Login</a>";
return;
}
$code = $_GET['code'];
//if we dont have a token, lets get one
if($access_token == null | $access_token == ""){
$access_token = getAccessToken();
}
// lets get some data from our devices!
getResource($access_token);
/*_____________________________________________________________________________________________________________________________________ */
// Get token
function getAccessToken() {
global $wink_oauth_url, $code, $client_secret;
echo "<b>getAccessToken()</b> Using Code: $code<br>";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $wink_oauth_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_HEADER, FALSE);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, "{
\"client_secret\": \"$client_secret\",
\"grant_type\": \"authorization_code\",
\"code\": \"$code\"
}");
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
$response = curl_exec($curl);
//var_dump($response);
formatResults($response); //debug output
curl_close($curl);
return json_decode($response)->access_token;
}
/*_____________________________________________________________________________________________________________________________________ */
// Get Resource(s) with our code & token
function getResource($access_token) {
global $devices_url;
echo "<b>getResource()</b> Using Token: $access_token<p>";
$header = array("Authorization: Bearer {$access_token}");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $devices_url,
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true
));
$response = curl_exec($curl);
curl_close($curl);
formatResults($response); //debug output
}
/*_____________________________________________________________________________________________________________________________________ */
//debug formatted output functions
function formatResults($json){
echo "<pre>";
echo json_encode(json_decode($json), JSON_PRETTY_PRINT);
echo "</pre>";
}
?>

Make HTTP GET request with cURL from Wowza Rest API

I have never used cURL before and I think I have hit a roadblock in my learning. I am trying to make a HTTP GET request to my Wowza server which uses the Rest API to return JSON results. The URL actually returns it in XML but Wowza support says it I can get the response in JSON by adding the content type as I have done.
$url = 'http://DOMAINNAME:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/live/instances/_definst_/incomingstreams/ncopeland';
$cURL = curl_init();
curl_setopt($cURL, CURLOPT_URL, $url);
curl_setopt($cURL, CURLOPT_HTTPGET, true);
curl_setopt($cURL, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json;charset=utf-8',
'Accept: application/json'
));
$result = curl_exec($cURL);
$result = json_decode($result,true);
curl_close($cURL);
The response should be this.
{
"serverName": "_defaultServer_",
"sourceIp": "ncopeland",
"isPTZEnabled": false,
"applicationInstance": "_definst_",
"name": "ncopeland",
"isRecordingSet": false,
"isStreamManagerStream": true,
"isPublishedToVOD": false,
"isConnected": true,
"ptzPollingInterval": 2000
}
But, instead the response is being returned and formatted like this.
{"serverName":"_defaultServer_","sourceIp":"ncopeland","isPTZEnabled":false,"applicationInstance":"_definst_","name":"ncopeland","isRecordingSet":false,"isStreamManagerStream":true,"isPublishedToVOD":false,"isConnected":false,"ptzPollingInterval":2000}
How can I format this so I can get these into usable variables. Really all I am needing from the response is "name" and "isConnected" so I can updated fields in a DB. Really all I am needing from the response is "name" and "isConnected" so I can updated fields in a DB like this.
Array (
[serverName] => _defaultServer_
[sourceIp] => ncopeland
[isPTZEnabled] => false
[applicationInstance] => _definst_
[name] => ncopeland
[isRecordingSet] => false
[isStreamManagerStream] => true
[isPublishedToVOD] => false
[isConnected] => false
[ptzPollingInterval] => false
)
So I can work with $obj variable as an array like so.
echo $obj['name'];
echo $obj['isConnected'];
I'm not sure what are you missing, everything should be working as intended from your code. The fact, that json returns data without newline, doesn't change how data will be used later.
$jsondata = '{"serverName":"_defaultServer_","sourceIp":"ncopeland","isPTZEnabled":false,"applicationInstance":"_definst_","name":"ncopeland","isRecordingSet":false,"isStreamManagerStream":true,"isPublishedToVOD":false,"isConnected":false,"ptzPollingInterval":2000}';
$result = json_decode($jsondata,true); //is array
var_dump ($result['serverName']);
var_dump ($result['isConnected']);
Besides that, keep in mind, that you cannot echo boolean values.
BTW, using objects is even simpler than arrays in my opinion.
$jsondata = '{"serverName":"_defaultServer_","sourceIp":"ncopeland","isPTZEnabled":false,"applicationInstance":"_definst_","name":"ncopeland","isRecordingSet":false,"isStreamManagerStream":true,"isPublishedToVOD":false,"isConnected":false,"ptzPollingInterval":2000}';
$result = json_decode($jsondata);
var_dump ($result->serverName);
var_dump ($result->isConnected);
There was nothing wrong with my code after all. Come to find out on my hosted server solution the package I was using from Bluehost blocked the ports I was needing to make the http request via cURL. I was able to upgrade to a dedicated IP to get the ports I was needing open so it would work and has been working great since.

Get order transaction ID from authorize.net Authorize AIM

I'm making a custom woocommerce reports plugin that will display certain information and spit it out as a .csv. I have it return stuff like name, company name, product, and amount. I do this the following way.
/**
* Check if we need customer phone.
*/
case 'wc_settings_tab_customer_phone':
array_push( $csv_values, self::customer_meta( get_the_ID(), '_billing_phone' ) );
break;
Now I'm using the Authorize.net AIM Payment Gateway for Woocommerce plugin so a Transaction ID is generated.
I want to include this in my .csv export. How would I go about doing this? I tried looking in the plugin files and noticed this is what the transaction id was $response_array[6] but can't figure out how to return it. If someone could show me how to tap into Authorize.net API and get the transaction ID that would be awesome! Thanks in advanced!
EDIT: Here is what I've got so far. I added the php code to connect but can't seem to pull the order transaction id. By the way, the "x_login" and "x_tran_key" have been taken out and replaced with "test123".
case 'wc_settings_tab_authorize_id':
$post_url = "https://secure.authorize.net/gateway/transact.dll";
$post_values = array(
// the API Login ID and Transaction Key must be replaced with valid values
"x_login" => "test123",
"x_tran_key" => "test123",
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
// Additional fields can be added here as outlined in the AIM integration
// guide at: http://developer.authorize.net
);
// This sample code uses the CURL library for php to establish a connection,
// submit the post, and record the response.
// If you receive an error, you may want to ensure that you have the curl
// library enabled in your php configuration
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($request, CURLOPT_POSTFIELDS, $post_string); // use HTTP POST to send form data
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
$post_response = curl_exec($request); // execute curl post and store results in $post_response
// additional options may be required depending upon your server configuration
// you can find documentation on curl options at http://www.php.net/curl_setopt
curl_close ($request); // close curl object
// This line takes the response and breaks it into an array using the specified delimiting character
$response_array = explode($post_values["x_delim_char"],$post_response);
array_push( $csv_values, TransactionID() );
break;
EDIT 2: Implementing John's code
case 'wc_settings_tab_authorize_id':
$post_url = "https://secure.authorize.net/gateway/transact.dll";
$post_values = array(
// the API Login ID and Transaction Key must be replaced with valid values
"x_login" => "test123",
"x_tran_key" => "test123",
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
// Additional fields can be added here as outlined in the AIM integration
// guide at: http://developer.authorize.net
);
// This sample code uses the CURL library for php to establish a connection,
// submit the post, and record the response.
// If you receive an error, you may want to ensure that you have the curl
// library enabled in your php configuration
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($request, CURLOPT_POSTFIELDS, $post_string); // use HTTP POST to send form data
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
$post_response = curl_exec($request); // execute curl post and store results in $post_response
// additional options may be required depending upon your server configuration
// you can find documentation on curl options at http://www.php.net/curl_setopt
curl_close ($request); // close curl object
$post_response = '1|1|1|This transaction has been approved.|4DHVNH|Y|2230582188|none|Test transaction for ValidateCustomerPaymentProfile.|0.00|CC|auth_only|none|John|Doe||123 Main St.|Bellevue|WA|98004|USA|800-555-1234|800-555-1234|email#example.com|||||||||0.00|0.00|0.00|FALSE|none|E440D094322A0D406E01EDF9CE871A4F||2|||||||||||XXXX1111|Visa||||||||||||||||';
$response_array = explode('|',$post_response);
$transaction_id = $response_array[6];
array_push( $csv_values, $transaction_id );
break;
EDIT 3: Okay, this is what I currently have (excluding the api and transaction key).
/**
* Check for authorize.net transaction id.
*/
case 'wc_settings_tab_authorize_id':
$post_url = "https://secure.authorize.net/gateway/transact.dll";
$post_values = array(
// the API Login ID and Transaction Key must be replaced with valid values
"x_login" => "TEST",
"x_tran_key" => "TEST",
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
// Additional fields can be added here as outlined in the AIM integration
// guide at: http://developer.authorize.net
);
// This sample code uses the CURL library for php to establish a connection,
// submit the post, and record the response.
// If you receive an error, you may want to ensure that you have the curl
// library enabled in your php configuration
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($request, CURLOPT_POSTFIELDS, http_build_query($post_values)); // use HTTP POST to send form data
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
$post_response = curl_exec($request); // execute curl post and store results in $post_response
// additional options may be required depending upon your server configuration
// you can find documentation on curl options at http://www.php.net/curl_setopt
curl_close ($request); // close curl object
// This line takes the response and breaks it into an array using the specified delimiting character
$response_array = explode($post_values["x_delim_char"],$post_response);
$transaction_id = $response_array[6];
array_push( $csv_values, $transaction_id );
break;
Still can't figure out why this won't work. When I try and return the $transaction_id I get the value 0. When I try $post_response to see what it returns I get this:
3|2|33|Credit card number is required.||P|0|||0.00|CC|auth_capture||||||||||||||||||||||||||THISISANALPHANUMERICNUMBER||||||||||||||||||||||||||||||
Before there was an alphanumberic string but I replaced it for security purposes. Do you think this may be happening because I'm not setting a cc number or billing address with it?
The response string returned by Authorize.Net is going to look something like this:
1|1|1|This transaction has been approved.|4DHVNH|Y|2230582188|none|Test transaction for ValidateCustomerPaymentProfile.|0.00|CC|auth_only|none|John|Doe||123 Main St.|Bellevue|WA|98004|USA|800-555-1234|800-555-1234|email#example.com|||||||||0.00|0.00|0.00|FALSE|none|E440D094322A0D406E01EDF9CE871A4F||2|||||||||||XXXX1111|Visa||||||||||||||||
This is the results separated by a | which is the delimiting character you set here:
"x_delim_char" => "|",
You correctly break apart the string using explode():
$response_array = explode($post_values["x_delim_char"],$post_response);
which gives us that data in an array called $response_array.
In Authorize.Net's response, the transaction ID is 2230582188. In our array that is the seventh element so we can get it using:
$transaction_id = $response_array[6];
Here is a demo showing you this works.

writing cURL like function in a rails app

I'm trying to convert this PHP cURL function to work with my rails app. The piece of code is from an SMS payment gateway that needs to verify the POST paramters. Since I'm a big PHP noob I have no idea how to handle this problem.
$verify_url = 'http://smsgatewayadress';
$fields = '';
$d = array(
'merchant_ID' => $_POST['merchant_ID'],
'local_ID' => $_POST['local_ID'],
'total' => $_POST['total'],
'ipn_verify' => $_POST['ipn_verify'],
'timeout' => 10,
);
foreach ($d as $k => $v)
{
$fields .= $k . "=" . urlencode($v) . "&";
}
$fields = substr($fields, 0, strlen($fields)-1);
$ch = curl_init($verify_url); //this initiates a HTTP connection to $verify_url, the connection headers will be stored in $ch
curl_setopt($ch, CURLOPT_POST, 1); //sets the delivery method as POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); //The data that is being sent via POST. From what I can see the cURL lib sends them as a string that is built in the foreach loop above
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //This verifies if the target url sends a redirect header and if it does cURL follows that link
curl_setopt($ch, CURLOPT_HEADER, 0); //This ignores the headers from the answer
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //This specifies that the curl_exec function below must return the result to the accesed URL
$result = curl_exec($ch); //It ransfers the data via POST to the URL, it gets read and returns the result
if ($result == true)
{
//confirmed
$can_download = true;
}
else
{
//failed
$can_download = false;
}
}
if (strpos($_SERVER['REQUEST_URI'], 'ipn.php'))
echo $can_download ? '1' : '0'; //we tell the sms sever that we processed the request
I've googled a cURL lib counterpart in Rails and found a ton of options but none that I could understand and use in the same way this script does.
If anyone could give me a hand with converting this script from php to ruby it would be greatly appreciated.
The most direct approach might be to use the Ruby curb library, which is the most straightforward wrapper for cURL. A lot of the options in Curl::Easy map directly to what you have here. A basis might be:
url = "http://smsgatewayadress/"
Curl::Easy.http_post(url,
Curl::PostField.content('merchant_ID', params[:merchant_ID]),
# ...
)

Categories