form result to metamask - ethereum

I'm trying to use the input from a form to create the details for a metamask transaction, taking form address and etherem amount then calling them with metamask. The metamask code works when hardcoded with address and amount. not sure where I'm going wrong.
run npx serve because metamask can be tricky.
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div>
<input onclick="fill_amount" id="amount" type="number" placeholder="eth">
<input onclick="fill_address" id="address" placeholder="address">
<button class="pay-button">Pay</button>
<div id="status"></div>
</div>
<script type="text/javascript">
window.addEventListener('load', async () => {
if (window.ethereum) {
window.web3 = new Web3(ethereum);
try {
await ethereum.enable();
initPayButton()
} catch (err) {
$('#status').html('User denied account access', err)
}
} else if (window.web3) {
window.web3 = new Web3(web3.currentProvider)
initPayButton()
} else {
$('#status').html('No Metamask (or other Web3 Provider) installed')
}
})
const initPayButton = () => {
$('.pay-button').click(() => {
// paymentAddress is where funds will be send to
var paymentAddress = document.getElementById("address").innerHTML
var amountEth = document.getElementById("amount").innerHTML
web3.eth.sendTransaction({
to: paymentAddress,
value: web3.toWei(amountEth, 'ether')
}, (err, transactionId) => {
if (err) {
console.log('Payment failed', err)
$('#status').html('Payment failed')
} else {
console.log('Payment successful', transactionId)
$('#status').html('Payment successful')
}
})
})
}
function fill_amount() {
var amountEth = document.getElementById("amount").innerHTML
}
function fill_address() {
var paymentAddress = document.getElementById("address").innerHTML
}
</script>
</body>
</html>

inside your fill_amount & fill_address functions you’re using the same variable of payment address. I believe inside the fill_amount function the variable should be amountEth not paymentAddress.

Related

WebSerial getPorts() method return nothing

I have tried Web Serial API.
If I use requestPort() method, like this :
<button id="connect">Connect</button>
<script>
const connectButton = document.getElementById("connect");
connectButton.addEventListener('click', async () => {
try {
const port = await navigator.serial.requestPort();
console.log(port)
} catch (e) {
console.error(e)
}
});
</script>
It's OK, to prompt the user for which device the site should be allowed to control.
But with getPorts() method, like this :
<script>
const connectButton = document.getElementById("connect");
connectButton.addEventListener('click', async () => {
try {
const ports = await navigator.serial.getPorts();
console.log(ports)
} catch (e) {
console.error(e)
}
});
</script>
I got nothing with ports.length == 0
Could anybody help this?
Thanks
A user must approve access to the device before it can be accessed. You initiate the request via:
navigator.serial.requestPort()
To get a list of ports that have already been selected/approved by the user from the permission popup you call:
navigator.serial.getPorts()
You can check out the https://webserial.io source for an example here:
https://github.com/williamkapke/webserial/blob/main/src/stores/connection.js#L41

Microsoft MSAL.js including domain_hint twice

I am using msal.js and wanted to use domain_hint to land directly on IdP page. After I set extraQueryParameters: {domain_hint: 'abc'}
msal.js does add the domain_hint=xyz to the query string but it is also adding domain domain_hint=organizations before that which led B2C to show the IdP selection page that I like to skip.
URL
https://xyz.b2clogin.com/xyz.onmicrosoft.com/b2csignupsignin/oauth2/v2.0/authorize?response_type=id_token&scope=https%3A%2F%test.onmicrosoft.com%2Fhelloapi%2Fdemo.read%20openid%20profile&client_id=e3443e90-18bc-4a23-9982-7fd5e67ff339&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F&state=11eff659-29d9-49af-80db-a7ef5bfe55ee&nonce=daeafcda-5984-468b-8796-1b2655a8599e&client_info=1&x-client-SKU=MSAL.JS&x-client-Ver=1.1.2&login_req=9b8396fa-6441-466d-98da-3efd87ab7d07-b2c_1_primerosignupsignin&domain_req=48e05529-88b8-40e1-825a-18c4e1077b3a&domain_hint=organizations&domain_hint=abc&client-request-id=f2e88cb1-5edb-447f-8fc3-578f69c23b4e&response_mode=fragment
Index.html
<head>
<title>Calling a Web API as a user authenticated with Msal.js app</title>
<style>
.hidden {
visibility: hidden
}
.visible {
visibility: visible
}
.response {
border: solid;
border-width: thin;
background-color: azure;
padding: 2px;
}
</style>
</head>
<body>
<!-- bluebird only needed if this page needs to run on Internet Explorer -->
<!-- msal.min.js can be used in the place of msal.js; included msal.js to make debug easy -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.4/bluebird.min.js" class="pre"></script>
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.1.2/js/msal.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" class="pre"></script>
<h2>Getting an access token with Azure AD B2C and calling a Web API</h2>
<div>
<div id="label">Sign-in with Microsoft Azure AD B2C</div>
<button id="auth" onclick="signIn()">Login</button>
<button id="callApiButton" class="hidden" onclick="callApi()">Call Web API</button>
</div>
<pre class="response"></pre>
<script class="pre">
// The current application coordinates were pre-registered in a B2C tenant.
var appConfig = {
b2cScopes: [""]
};
</script>
<script>
"use strict";
// configuration to initialize msal
const msalConfig = {
auth: {
clientId: "e3443e90-18bc-4a23-9982-7fd5e67ff339", //This is your client ID
authority: "https://xyz.b2clogin.com/xyz.onmicrosoft.com/B2c_SignUpSignIn", //This is your tenant info
validateAuthority: false
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
// instantiate MSAL
const myMSALObj = new Msal.UserAgentApplication(msalConfig);
// request to signin - returns an idToken
const loginRequest = {
scopes: appConfig.b2cScopes,
extraQueryParameters: {domain_hint: 'abc'}
};
// request to acquire a token for resource access
const tokenRequest = {
scopes: appConfig.b2cScopes
};
// signin and acquire a token silently with POPUP flow. Fall back in case of failure with silent acquisition to popup
function signIn() {
myMSALObj.loginPopup(loginRequest).then(function (loginResponse) {
getToken(tokenRequest).then(updateUI);
}).catch(function (error) {
logMessage(error);
});
}
//acquire a token silently
function getToken(tokenRequest) {
return myMSALObj.acquireTokenSilent(tokenRequest).catch(function(error) {
console.log("aquire token popup");
// fallback to interaction when silent call fails
return myMSALObj.acquireTokenPopup(tokenrequest).then(function (tokenResponse) {
}).catch(function(error){
logMessage("Failed token acquisition", error);
});
});
}
// updates the UI post login/token acqusition
function updateUI() {
const userName = myMSALObj.getAccount().name;
console.log(myMSALObj.getAccount());
logMessage("User '" + userName + "' logged-in");
// add the logout button
const authButton = document.getElementById('auth');
authButton.innerHTML = 'logout';
authButton.setAttribute('onclick', 'logout();');
// greet the user - specifying login
const label = document.getElementById('label');
label.innerText = "Hello " + userName;
// add the callWebApi button
const callWebApiButton = document.getElementById('callApiButton');
callWebApiButton.setAttribute('class', 'visible');
}
// calls the resource API with the token
function callApi() {
getToken(tokenRequest).then(function(tokenResponse) {
callApiWithAccessToken(tokenResponse.accessToken);
});
}
// helper function to access the resource with the token
function callApiWithAccessToken(accessToken) {
// Call the Web API with the AccessToken
$.ajax({
type: "GET",
url: appConfig.webApi,
headers: {
'Authorization': 'Bearer ' + accessToken,
},
}).done(function (data) {
logMessage("Web APi returned:\n" + JSON.stringify(data));
})
.fail(function (jqXHR, textStatus) {
logMessage("Error calling the Web api:\n" + textStatus);
})
}
// signout the user
function logout() {
// Removes all sessions, need to call AAD endpoint to do full logout
myMSALObj.logout();
}
// debug helper
function logMessage(s) {
document.body.querySelector('.response').appendChild(document.createTextNode('\n' + s));
}
</script>
</body>
</html>

AngularJS: Pass textbox value to services

I am new in angularJS. Currently working on services. I tried to pass text-box value to services. I don't know how to pass. I code but it's not working.
app.service("wishService", function ($timeout) {
this.wishHim = function (_wishMessage) {
$timeout(function () {
alert('Hi ,' + _wishMessage);
}, 2000);
}
});
app.controller('wishCtrl', ['$scope', function ($scope, wishService) {
$scope.Message = "";
$scope.SendMessage = function (wishMessage) {
wishService.wishHim(wishMessage);
};
}]);
<div ng-controller="wishCtrl">
Wish Message: <input type="text" ng-model="wishMessage" />
<input type="button" value="Send Message" ng-click="SendMessage(wishMessage)" /><br />
Your Message : {{Message}}
</div>
DEMO
wishService injection problem
app.controller('wishCtrl', ['$scope', 'wishService', function ($scope, wishService) {
$scope.Message = "";
$scope.SendMessage = function (wishMessage) {
wishService.wishHim(wishMessage);
};
}]);
I fixed your code, see the PLUNK here. While what Sandeep said is correct, you also had a TON of other problems. Refer to what I changed.
Edit: It was brought to my attention that what I changed your code to is the format of a factory, rather than a service:
app.service("MessageService", function () {
var service = {
msg: undefined,
setMsg: function(msg){
this.msg = msg;
},
getMsg: function(msg){
return this.msg;
}
}
return service;
});

how to authenticate myself asynchronously on the Google Drive API using AngularJS and HTML

Could someone determine how to authenticate myself asynchronously on the Google Drive API using AngularJS and HTML?
I am getting stuck on the call to gapi.auth.authorize because the callback function never gets called:
Here is the AngularJS--HTML5 code excerpt which does not work currently,
var app = angular.module('myApp', []);
app.service('googleService', ['$http', '$rootScope', '$q', function ($http, $rootScope, $q) {
this.login = function () {
gapi.auth.authorize(
{ client_id: '1009536034660-armd84ckoemm3jan35ceupjhdsmo0fa1.apps.googleusercontent.com', scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email' , immediate: true },
this.handleAuthResult);
return deferred.promise;
}
this.handleClientLoad = function {
gapi.client.setApiKey(apiKey);
gapi.auth.init(function () { });
window.setTimeout(checkAuth, 1);
};
this.checkAuth = function () {
gapi.auth.authorize({
client_id: clientId,
scope: scopes,
immediate: true,
hd: domain
}, this.handleAuthResult);
};
this.handleAuthResult = function (authResult) {
if (authResult && !authResult.error) {
var data = {};
gapi.client.load('oauth2', 'v2', function () {
var request = gapi.client.oauth2.userinfo.get();
request.execute(function (resp) {
data.email = resp.email;
deferred.resolve(data);
});
});
} else {
deferred.reject('error');
}
};
this.handleAuthClick = function (event) {
gapi.auth.authorize({
client_id: clientId,
scope: scopes,
immediate: false,
hd: domain
}, this.handleAuthResult);
return false;
};
}]);
app.controller('myController', ['$scope', 'googleService', function ($scope, googleService) {
$scope.login = function () {
$scope.login = function () {
googleService.login().then(function (greeting) {
console.log('Success: ' + greeting);
}, function (reason) {
console.log('Failed: ' + reason);
}, function (update) {
console.log('Got notification: ' + update);
});
};
};
}]);
} else {
deferred.reject('error');
}
};
});
Why is the gapi.auth.authorize failing to call the callback?
First I checked this hypothesis stackoverflow.com/questions/20036893/… and it was incorrect. Next I checked this hypothesis : stackoverflow.com/questions/31659414/… and it was also wrong.
I even tried using Brendan's SetTimeout workaround in this URL, https://groups.google.com/forum/#!topic/google-api-javascript-client/GuFxPzqQ9-0 and it did not function properly.
In addition, I requested and obtained a new OAuth2 client id with the correct javascript origin. Evidently , the onload callback is only called after successful loading of the script. Or, is there a timeout possibility for the callback to be invoked?
Here is Windows 7 ASP.NET program written entirely in Javascript and HTML which works properly :
<html>
<head>
<title>Google+ Sign-in button demo: rendering with JavaScript</title>
<style type="text/css">
html, body { margin: 0; padding:0;}
#signin-button {
padding: 5px;
}
#oauth2-results pre { margin: 0; padding:0; width: 600px;}
.hide { display: none;}
.show { display: block;}
</style>
<script src="https://apis.google.com/js/client:platform.js" type="text/javascript"></script>
<script type="text/javascript">
var loginFinished = function (authResult) {
if (authResult) {
console.log(authResult);
}
gapi.client.load('oauth2', 'v2', function () {
gapi.client.oauth2.userinfo.get()
.execute(function (resp) {
// Shows user email
console.log(resp.email);
});
});
};
var options = {
'callback': loginFinished,
'approvalprompt': 'force',
'clientid': '375218714272ao7690jhv6sk7jphi0jf3l5t500sajvt.apps.googleusercontent.com',
'scopes': ['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/drive.readonly'],
'requestvisibleactions': 'http://schemas.google.com/CommentActivity http://schemas.google.com/ReviewActivity',
'cookiepolicy': 'single_host_origin'
};
var renderBtn = function () {
gapi.signin.render('renderMe', options);
}
</script>
</head>
<body onload ="renderBtn()">
<div id="renderMe"></div>
</body>
</html>
Could I ask why the Windows 7 ASP.NET Javascript code works okay but not the AngularJS code version?
You have to point $window.location.href at a file in the Windows filesytem which conforms to JavaScript origin naming convention.

How can I pass data from a service into my controller?

Okay so right now I am messing around with the ionic framework and learning angularJS at the same time. I just came across $q and async calls, but I just can't seem to get it right. I want to be able to parse a JSON file which I already have set up using GetJsonSpecials then pass that to GetData which will then pass it to my controller SpecialsCtrl so I can attach it to $scope. I know I am not understanding the promises correctly because everything inside SpecialService undefined. I can get the data perfectly fine from the other two serivces, but when I try passing it to SpecialService it all just seems to crumble which in turn ends up as undefined in my controller. Maybe I am not going about this the right way? Are there any best practices of doing this kind of thing?
angular.module('starter.controllers', [])
.controller('SpecialsCtrl', function ($scope, SpecialService) {
$scope.specials = SpecialService.all();
console.log("Specials Controller: Got Data", $scope.specials);
})
//Create methods to access the specials inside the controller in which we inject this in
.factory('SpecialService', function (GetData) {
var specials = GetData.getSpecials();
console.log("DATAAAA: ", specials);
return {
// Return all specials
all: function () {
console.log("Inside return with specials: ", specials);
return specials;
},
getSpecialWithId : function (specialId) {
// Simple index lookup
return specials[i];
}
}
}
})
.factory('GetData', function(GetJsonSpecials) {
return {
getSpecials : function() {
GetJsonSpecials.retrieveData().then(function (data) {
console.log("Got the JSON data", data);
return data;
}, function (status) {
alert("Error getting specicals", status);
console.log("Error getting specicals", status);
});
}
}
})
//Asynchronously get the specials from the json file
.factory('GetJsonSpecials', function ($q, $http) {
return {
retrieveData : function() {
var deferred = $q.defer();
$http.get('js/specials.json').success(function (data, status) {
deferred.resolve(data);
}).error(function (status) {
deferred.reject(status);
console.log("Error in handling json!");
});
return deferred.promise;
}
}
})
The reason I have this overly complicated is because in the end I want to be able to share the data to another controller which will display that specific specials' properties in a new view.
.controller('DetailCtrl', function ($scope, $stateParams, JsonSpecials, $firebaseAuth) {
$scope.id = parseInt($stateParams.specialId);
$scope.special = JsonSpecials.getSpecialWithId($scope.id);
})
There are a few problems here. The main issue being that angularjs promises are asynchronous and you're trying to use them in a synchronous manner.
First off, you having an extra } after your SpecialService definition.
In your SpecialService:
.factory('SpecialService', function (GetData) {
var specials = GetData.getSpecials();
This will be nothing because your GetData.getSpecials() returns nothing.
If you were to fix GetData.getSepcials to return:
getSpecials : function() {
return GetJsonSpecials.retrieveData().then(function (data) {
console.log("Got the JSON data", data);
return data;
}, function (status) {
alert("Error getting specicals", status);
console.log("Error getting specicals", status);
});
}
then back in your SpecialService, you need to change how you get the data back.
var specials = GetData.getSpecials();
won't give you your data either. It will be a promise because it is asynchronous. So it needs to be
GetData.getSpecials().then(function(data) {
return data;
});
Also, as Matt as pointed out, in your retrieveData definition, you're creating an unnecessary promise. So
retrieveData : function() {
var deferred = $q.defer();
$http.get('js/specials.json').success(function (data, status) {
deferred.resolve(data);
}).error(function (status) {
deferred.reject(status);
console.log("Error in handling json!");
});
return deferred.promise;
}
is the same as:
retrieveData : function() {
return $http.get('js/specials.json').error(function (status) {
console.log("Error in handling json!");
return status;
});
}
It seems you are over complicating things a bit. You're passing data around factories for no clear reason. I think those three factories could be combined into just one. Maybe try something like..
index.html
<!DOCTYPE html>
<html ng-app="foobar">
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div ng-controller="SpecialsCtrl">
{{specials}}
</div>
<div ng-controller="AnotherController">
{{specials}}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
script.js
angular.module('foobar', [])
.controller('SpecialsCtrl', function ($scope, JsonSpecials) {
JsonSpecials.retrieveData().then(function(data){
$scope.specials = data;
});
})
.controller('AnotherController', function ($scope, JsonSpecials) {
JsonSpecials.retrieveData().then(function(data){
$scope.specials = data;
});
})
//$http returns a promise anyway so you don't need $q
.factory('JsonSpecials', function ($http){
return {
retrieveData : function() {
return $http
.get('js/specials.json')
.error(function (status) {
console.log("Error in handling json!");
});
}
}
});