Call Solana web3.js from HTML - web3js

I am trying to run web3.js from HTML. Now so far I have been able to call window.solana.connect(); and window.solana.disconnect(); functions. However when I try run below code it doesn't work. I have tested it various options, like removing "web3." from the code but still didn't work. I would apprecaite if someone can guide me on how I can establish the connection.
const connection = new web3.Connection(web3.clusterApiUrl("devnet"));
Majority of my codes below is from the research done on Stackoveflow. Links below:
Solana : Adding Sollet / Phantom Wallet Connect to my website - Steps?
I would like to mint a new token on solana. How can I do this using solana-web3.js?
How can you transfer SOL using the web3.js sdk for Solana?
How to properly transfer Solana SOL using web3js via Phantom
Unfortunately docs on Phantom website don't help either. https://docs.phantom.app/integrating/establishing-a-connection
My existing codes below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to Decentralized Ecommerce</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/3.0.0-rc.5/web3.min.js" integrity="sha512-jRzb6jM5wynT5UHyMW2+SD+yLsYPEU5uftImpzOcVTdu1J7VsynVmiuFTsitsoL5PJVQi+OtWbrpWq/I+kkF4Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="{{ url_for('static', filename='app.js') }}"></script>
<script src="https://unpkg.com/#solana/web3.js#latest/lib/index.iife.js"></script>
<script src="/static/solana.js"></script>
<script type="text/javascript">
async function transferSOL() {
//Changes are only here, in the beginning
if (window.solana.isConnected === false){
const resp = await window.solana.connect();
}
const pubKey = await window.solana.publicKey;
console.log("Public Key: ", pubKey);
// Establishing connection
const connection = new web3.Connection(web3.clusterApiUrl("devnet"));
alert('hello2');
// I have hardcoded my secondary wallet address here. You can take this address either from user input or your DB or wherever
var recieverWallet = new web3.PublicKey("4iSD5Q6AnyhRHu6Uz4u1KAzXh3TwNwwQshEGhZbEXUTw");
alert('hello3');
// Airdrop some SOL to the sender's wallet, so that it can handle the txn fee
var airdropSignature = await connection.requestAirdrop(
provider.publicKey,
web3.LAMPORTS_PER_SOL,
);
// Confirming that the airdrop went through
await connection.confirmTransaction(airdropSignature);
console.log("Airdropped");
var transaction = new web3.Transaction().add(
web3.SystemProgram.transfer({
fromPubkey: provider.publicKey,
toPubkey: recieverWallet,
lamports: web3.LAMPORTS_PER_SOL //Investing 1 SOL. Remember 1 Lamport = 10^-9 SOL.
}),
);
// Setting the variables for the transaction
transaction.feePayer = await provider.publicKey;
let blockhashObj = await connection.getRecentBlockhash();
transaction.recentBlockhash = await blockhashObj.blockhash;
// Transaction constructor initialized successfully
if(transaction) {
console.log("Txn created successfully");
}
// Request creator to sign the transaction (allow the transaction)
let signed = await provider.signTransaction(transaction);
// The signature is generated
let signature = await connection.sendRawTransaction(signed.serialize());
// Confirm whether the transaction went through or not
await connection.confirmTransaction(signature);
//Signature or the txn hash
console.log("Signature: ", signature);
}
</script>
</head>

After importing the script on the HTML:
<script src="https://unpkg.com/#solana/web3.js#latest/lib/index.iife.js"> </script>
You should be able to call:
const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl("mainnet-beta"));
Note it is solanaWeb3 not web3

Here is an example with Solana Web3 1.4:
import { Connection, clusterApiUrl } from "#solana/web3.js";
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
Make sure to have installed the library via, npm install #solana/web3.js.

Related

How to use server side rendering in order to add og meta-tags in react?

What I need is to change the content of og:title in a dynamic way into index.blade.php by using express server. As you know, the only way to change the content of the tags is by using server side rendering because facebook cannot read og tags if they added by react helmet component. So, here what I did:
Into index.balde.php I added these lines:
<meta property="og:title" content="$OG_TITLE">
<meta property="og:description" content="$OG_DESCRIPTION">
Then I created server.js file in order to change the content of the tags dynamically through the server:
var express = require('express');
var app = express();
const path = require('path');
const fs = require('fs')
app.get('/profile', function(request, response) {
console.log("Entered the logic");
const filePath = path.resolve(__dirname, '../views', 'index.blade.php');
// read in the index.html file
fs.readFile(filePath, 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
let result = null;
// replace the special strings with server generated strings
data = data.replace(/\$OG_TITLE/g, 'PROFILE TITLE');
result = data.replace(/\$OG_DESCRIPTION/g, "PROFILE DESCRIPTIONS");
//result = data.replace(/\$OG_IMAGE/g, 'https://i.imgur.com/V7irMl8.png');
response.send(result);
});
});
app.listen(5000, function(){
console.log('listening on *:' + 5000);
});
As a result, when I open www.testurl.com:5000/profile The content of the tags have been changed successfully, but my problem is how to make the content of the tags changed without need to add the port number in url, since the requested link should be without the port number. The user does not need to add port number into the URL.
Is there anyway in react/express to let the server know that when user call www.testurl.com/profile all event listener in the server on port 500 should be called (on other way when access the url without port number app.get('/profile',...) should be called)? Or there is a way to call the url with port number into the basic component to make the event each time user open any page inside the app?
I am really need a help, since i spent a lot of time in order to find a solution. Thanks.

How to get a tensor from an image

I have an image and I would like to get the tensor from it.
Some of the images are already on the frontend server be whereas others will be served by the server
To do that, one needs to use fromPixels
In case the image is already displayed in an html page
You can consider doing a querySelector to get the image first and then you can use fromPixels
html
<img id="my-image" src="mydata.jpg">
js
const image = document.querySelector("#my-image")
const t = tf.fromPixels(image)
If the image is not present in the html page, you can use the constructor Image to create it and then pass it as parameter to fromPixels
const im = new Image()
im.onload = () => {
const a = tf.fromPixels(im, 4)
a.print()
console.log(a.shape)
}
im.src = "url-of-the-image"
document.body.appendChild(im)
onload makes sure that the image has finished downloading before converting it to a tensor.
If the image url and the url on which the frontend page is served are different there will be a cross-origin issue when creating the tensor. If the server serves the image with an access control that allows the frontend to retrieve that image, then setting the crossOrigin attribute of the image will solve the issue, otherwise there will nothing that can be done to get the tensor from that image.
const im = new Image()
im.crossOrigin = "anonymous";
im.src = "https://i.imgur.com/lVlPvCB.gif"
document.body.appendChild(im)
im.onload = () => {
const a = tf.fromPixels(im, 4)
a.print()
console.log(a.shape)
}
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.12.4/tf.js"> </script>
</head>
<body>
</body>
</html>

AngularJS & Flask : Passing data to html

I am trying to send the data from Flask to AngularJS.
Server
#app.route("/data")
def getDataFromDB():
cur.execute("select * from employee")
rows = cur.fetchall()
columns = [desc[0] for desc in cur.description]
result = []
for row in rows:
row = dict(zip(columns, row))
json_row=json.dumps(row)
result.append(json_row)
json_response=json.dumps(result)
response=Response(json_response,content_type='application/json; charset=utf-8')
response.headers.add('content-length',len(json_response))
response.status_code=200
return response
Client
maincontroller.js
var app=angular.module('myApp',[]);
app.controller("MainController", function($scope,$http){
var done=function(resp){
$scope.lists=resp.data;
};
var fail=function(err){
};
$http.get('http://10.62.XX.XX:8083/data')
.then(done,fail);
});
index.html
<!DOCTYPE html>
<head>
<title>Learning AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"
type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
<script src="maincontroller.js" type="text/javascript"></script>
</head>
<body ng-app="myApp">
<div id='content' ng-controller='MainController'>
<div>
<ul>
<li ng-repeat='ele in list'>{{ele}}</li>
</ul>
</div>
</div>
</body>
</html>
Now, when I access the above code using jsbin.com, I can see my api getting called but nothing is visible on the output screen in jsbin. It is blank.
But when I put the same code in eclipse, I see no api call happening. Do I need to do something more to make angularJS work? I just open the index.html with web browser.
If the IP is not your local machine you need to setup CORS on the server. I am not familiar with Flask but it looks like there is a package that handles this. I also found a function that sets up CORS for Flask.
from datetime import timedelta
from flask import Flask, make_response, request, current_app
from functools import update_wrapper
def crossdomain(origin=None, methods=None, headers=None, max_age=21600, attach_to_all=True, automatic_options=True):
if methods is not None:
methods = ', '.join(sorted(x.upper() for x in methods))
if headers is not None and not isinstance(headers, basestring):
headers = ', '.join(x.upper() for x in headers)
if not isinstance(origin, basestring):
origin = ', '.join(origin)
if isinstance(max_age, timedelta):
max_age = max_age.total_seconds()
def get_methods():
if methods is not None:
return methods
options_resp = current_app.make_default_options_response()
return options_resp.headers['allow']
def decorator(f):
def wrapped_function(*args, **kwargs):
if automatic_options and request.method == 'OPTIONS':
resp = current_app.make_default_options_response()
else:
resp = make_response(f(*args, **kwargs))
if not attach_to_all and request.method != 'OPTIONS':
return resp
h = resp.headers
h['Access-Control-Allow-Origin'] = origin
h['Access-Control-Allow-Methods'] = get_methods()
h['Access-Control-Max-Age'] = str(max_age)
if headers is not None:
h['Access-Control-Allow-Headers'] = headers
return resp
f.provide_automatic_options = False
return update_wrapper(wrapped_function, f)
return decorator
#app.route('/')
#crossdomain(origin='*')
def landing():
return jsonify(i_am_a='cross domain resource!')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)

channel in trivial GAE app not getting 'onmessage'

I am trying to create the smallest possible GAE app to show the use of the channel api.
I have two handlers in the python, the first "TestPage" sends out the html shown below. The second "SendPage" tries to send a message over the channel to the test page. The code for the TestPage is
class TestPage(Handler):
def get(self):
token = channel.create_channel("1")
self.render("test.html", token = token)
It just creates the channel with an id of "1" and reders the page with the token passed back from create_channel().
The SendPage is just:
class SendPage(Handler):
def get(self):
channel.send_message("1", "hello")
self.write("sent hello to 1")
The html is as small as I could get it:
<!DOCTYPE HTML>
<html>
<body>
<br>Token is {{ token }}
<br>
<div id="debug">_</div>
<!--
<script src="https://talkgadget.google.com/talkgadget/channel.js"></script>
-->
<script src="static/channel.js"></script>
<script defer="defer">
function debug(s) {
document.getElementById("debug").innerHTML = s;
}
var channel = new goog.appengine.Channel( {{ token }} );
var socket = channel.open();
socket.onopen = function(e) {
debug("open");
}
socket.onclose = function(e) {
debug("close");
}
socket.onerror = function(e) {
debug("error");
}
socket.onmessage = function(e) {
debug("message");
}
debug("ready");
</script>
</body>
</html>
So, inside chrome I pull up TestPage and I see the "ready" message. Then I pull up the SendPage in another tab. And see the "sent message". Then when I go back to the TestPage I would expect to have "ready" replaced by "message". But this never happens. None of the socket handler functions are being called.
I'm stuck for the moment and would appreciate any help or suggestions.
Thank you.
Ok, I figured it out. There were two problems. First, the template line
var channel = new goog.appengine.Channel( {{ token }} );
should have been
var channel = new goog.appengine.Channel( "{{token}}" );
as it was token was something like "channel-2052893164-1373347311-1" which quietly evaluated to a number.
Second, the correct script for the channel.js was
<script type="text/javascript" src="/_ah/channel/jsapi"></script>
The other scripts I had referenced were from other stack overflow answers and I guess they did not properly apply to this problem.
Thanks.

Login Test with Jenkins and Symfony2

I configured jenkins in order to automating the tests for my project. The unit tests work well. Now I want to do some test with my database. For example the login test: enter the username, the password (submit the form). Do you have an idea of how to do this? Thank you.
Here is the test I want to do but it does not work:
Get the home page, test if the link FAQ is present two times, click on the first FAQ link, test if the link RMK is present, click on login, test if forgot password link is present, enter my username and my password submit the form, get the profile page, test if My Profile link is present.
<?php
namespace RMK\SocialBundle\Tests\FunctionalTests\Controller\Website;
use RMK\SocialBundle\Controller\Website;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Bundle\FrameworkBundle\Controller\RedirectController;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
class HomeControllerTest extends WebTestCase
{
public function testViewFAQ(){
$client = static::createClient();
$crawler = $client->request('GET', '/home');
$this->assertEquals(2, $crawler->filter('a:contains("FAQ")')->count());
$this->assertEquals(2, $crawler->filter('a:contains("FAQ")')->count());
$faqlink = $crawler->filter('a:contains("FAQ")')->eq(0)->link();
$crawler = $client->click($faqlink);
$this->assertEquals(1, $crawler->filter('a:contains("RMK")')->count());
$loginLink = $crawler->filter('a:contains("Login")')->eq(0)->link();
$crawler = $client->click($loginLink);
$this->assertEquals(1, $crawler->filter('a:contains("Forgot Password?")')->count());
$form = $crawler->selectButton('_submit')->form();
$form['_username'] = 'username';
$form['_password'] = 'test';
$crawler = $client->submit($form);
$crawler = $client->followRedirect();
$crawler = $client->request('GET', '/profile');
$this->assertEquals(1, $crawler->filter('a:contains("My Profile")')->count());
}
}
?>
The last assert failed by saying: Failed asserting that 0 matches expected 1. When I put var_dump(print_r($client->getResponse()->getContent())); just before this last assert I got this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="refresh" content="1;url=/home" />
<title>Redirecting to /home</title>
</head>
<body>
Redirecting to /home.
</body>
</html>bool(true)
I am sure I am missed something but I don't know what. Do you have an idea? Thx.
P.S: I am on Ubuntu 12.04.

Resources