I am new to blockchain. I really couldn't understand how to add logo to my erc20 crypto token on polygon before listing it on any coin market.
I want to add my own custom image to the circular portion. How can I change this current logo to something new and If I transfer the token to some other account, my custom logo will be displayed?
Please help.
MetaMask implements the EIP-747 standard (currently unfinished in May 2022) and its wallet_watchAsset method to display custom token logo.
Mind that this is not a centralized database of logos per token address, so each MetaMask instance can theoretically display a different logo for the same token. And that users need to explicitly add the logo either manually or by confirming a MetaMask popup opened by a snippet from your web app.
Code example from MetaMask docs:
const wasAdded = await ethereum.request({
method: 'wallet_watchAsset',
params: {
type: 'ERC20', // Initially only supports ERC20, but eventually more!
options: {
address: tokenAddress, // The address that the token is at.
symbol: tokenSymbol, // A ticker symbol or shorthand, up to 5 chars.
decimals: tokenDecimals, // The number of decimals in the token
image: tokenImage, // A string url of the token logo
},
},
});
Related
I've been trying to make an NFT marketplace with the functionality of auctioning an item. But I don't know how to achieve this via signing transaction.
I have tried to use almost every method of signing from web3.js, but it requires the private key of the user.
However there's the function web3.eth.signTransaction which doesn't require any private key to sign the transaction, but it gives an error on the console. saying : Error: The method 'eth_signTransaction' does not exist / is not available.
Can someone give me an overview of how this signing and sending transaction can be done implementing the functionality of auctioning an nft like nft marketplaces: opensea or foundation.
From the docs:
Signs a transaction. This account needs to be unlocked.
It doesn't require the private key, but it requires the account (that is used for signing the transaction) to be unlocked on the node. Which means the node needs to hold the private key to unlock the account.
It's usually allowed on local nodes such as Ganache or private nodes.
And public nodes such as Infura usually disable this functionality (hence the error message "eth_signTransaction is not available") since they don't store your private keys.
You can ask the user to sign the transaction using their wallet. For example using MetaMask (or any other wallet implementing the Ethereum provider API):
const transactionParameters = {
from: ethereum.selectedAddress, // must match user's active address
to: 'your address'
};
await ethereum.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
});
I have implemented the chrome.identity launchWebAuthFlow to authenticate users of a web extension against an oauth2 provider and the entire flow works perfectly, I receive the access token back in the redirect URL, I extract the token using a regex and then it is valid and accepted to query the APIs.
However, I do not understand why it does not prompt anymore for credentials when I launch again the launchWebAuthFlow. Instead, it retrieves another (valid !) token in the background. Don't get me wrong, I like this, and I prefer it works in the background, but I just don't understand how. Even after clearing all cookies and local data, when I launch the launchWebAuthFlow again it just works in the background without asking for credentials...where are they stored?
Also, not sure if that helps, but my flow is the following:
extension ->oauth2 server->azure ad SSO->enter credentials->redirect to extension
So the real authentication is managed by Azure AD. However, even when I'm signed out from Microsoft, the extension keeps getting a valid auth token when the below code is triggered and without asking for credentials...so the credentials must be stored somewhere...
chrome.identity.launchWebAuthFlow(
{
url: dev.identity_url(),
interactive: true
},
function (responseWithToken) {
// the access token needs to be extracted from the response.
console.log(responseWithToken);
let token = responseWithToken.match(/(?<=access_token=).*(?=&token_type)/);
token = token[0];
chrome.storage.local.set({ "auth-token": token }, function () {
console.log(`Access Token has been saved: ${token}`);
});
}
);
I know that when I create a payment method I can use failOnDuplicatePaymentMethod to block duplicate cards. But when I use the storeInVaultOnSuccess option with Braintree_Transaction::sale, what is the best way to not save the card if it is already saved?
Edit:
Let me clarify my situation to make sure. On my checkout page I am currently using this JavaScript:
braintree.setup(
myToken,
'custom',
{
id: 'my-form-id',
hostedFields: {
...
},
onPaymentMethodReceived: function(obj) {
...
},
onError: function(obj) {
...
}
}
);
The customer fills in their CC number, CVV and expiration date and clicks submit and then that onPaymentMethodReceived callback fires. In that JS callback I make an AJAX call to my back-end and pass the nonce. On the back-end I call Braintree_Transaction::sale in order to charge the customer.
I always need Braintree_Transaction::sale to successfully complete so that the sale goes through. And then in addition so this sale, I want the card to be saved if the customer has checked "save my card" and the card isn't already saved.
On this checkout page, the customer does have the option to select a saved card instead of inputting all their card info again, but they may type all the card info in again(for an already saved card) instead of selecting the saved card.
How would you do it given this setup? Does your below setup still apply? If so how exactly would I integrate the below with my above setup? Or do I need to rearrange my UI/UX for this(I think this is a pretty standard checkout flow)?
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
There isn't a way to prevent duplicate payment methods when making a Braintree_Transaction::sale API call. However, you can still achieve your goal with some settings on your client. Here are those steps:
On your server, create a client token and include the customer_ID and the failOnDuplicatePaymentMethod parameters:
```
$clientToken = $gateway->clientToken()->generate([
"customerId" => "aCustomerId",
"options" => [
"failOnDuplicatePaymentMethod" => true
] ]);
```
Use this client token as your authorization when creating the Braintree client instance:
```
var createClient = require('braintree-web/client').create;
createClient({
authorization: CLIENT_AUTHORIZATION
}, function (createErr, clientInstance) {
// ...
});
Per Braintree's docs regarding generating a client Token,
If [the failOnDuplicatePaymentMethod] option is passed and the same payment method has already been
added to the Vault for any customer, the request will fail. This can
only be passed if a $customerId is passed as well. If the check fails,
this option will stop the Drop-in from returning a
$paymentMethodNonce. This option will be ignored for PayPal, Pay with
Venmo, Apple Pay, and Google Pay payment methods.
I'm trying to set a user's OU from an App Script inside App Maker.
(user is a variable with an email address)
function getUser(user) {
var x = AdminDirectory.Users.update(
{
orgUnitPath: "/",
userKey: user,
});
console.log("function ran");
}
This code errors with:
Exception: Invalid number of arguments provided. Expected 2-3 only at getUser (ServerScripts:107)
Invalid number of arguments provided. Expected 2-3 only
at getUser (ServerScripts:107)
at getUser (ClientHandoff:21:21)
at TestMoveOU.Panel1.Button1.onClick:1:1
What am I doing wrong here? Looking at the docs, you only need to provide the properties you're changing.
The Apps Script documentation says the following:
For detailed information on this service, see the reference documentation for the Admin SDK Directory API. Like all advanced services in Apps Script, the Admin SDK Directory service uses the same objects, methods, and parameters as the public API.
Therefore, we need to consult the documentation to get clarification on how to achieve this.
The method requires at least two parameters: that means that the the first parameter is a user object resource and the second parameter is the email address of the user: AdminDirectory.Users.update(resource, userKey). So you need to do this:
function getUser(user) {
var userResource = {
orgUnitPath: "/"
};
var updated = AdminDirectory.Users.update(userResource, user);
console.log(updated.primaryEmail);
}
So why do you need to specify the user email in the method when it is already being specified in the userResource object? Well, the email address in the userResource object would be the new value, in case you want to change the email address.
P.S. Perhaps you might wanna change the name of the function to something that is more of a match; updateUser() perhaps? I hope this helps!
I was able to connect and upload videos using the library but when I deleted the app connection on Vimeo.com (as a test) the app didn't authorize again.
the upload looks like it's working but nothing is uploaded as the app is no longer connected.
I deleted the app on the phone and restarted but it still won't re-authorize the app.
This comes up in the output:
Vimeo upload state : Executing
Vimeo upload state : Finished
Invalid http status code for download task.
And this is in OldVimeoUpload.swift: ( didn't include the actual access code!)
import Foundation
class OldVimeoUpload: VimeoUpload
{
static var VIMEO_ACCESS_TOKEN :String! // = "there's a string of numbers here"
static let sharedInstance = OldVimeoUpload(backgroundSessionIdentifier: "") { () -> String? in
return VIMEO_ACCESS_TOKEN // See README for details on how to obtain and OAuth token
}
// MARK: - Initialization
override init(backgroundSessionIdentifier: String, authTokenBlock: AuthTokenBlock)
{
super.init(backgroundSessionIdentifier: backgroundSessionIdentifier, authTokenBlock: authTokenBlock)
}
}
It looks like the access token number is commented out. I deleted the 2 forward slashes to see if that would fix it but it didn't.
I spoke too soon.
It sounds like you went to developer.vimeo.com and created an auth token. Used it to upload videos. And then went back to developer.vimeo.com and deleted the auth token.
The app / VimeoUpload will not automatically re-authenticated in this situation. You've killed the token and the app cannot request a new one for you. You'll need to create a new auth token and plug it into the app.
If this is not accurate and you're describing a different issue let us know.
If you inspect the error that's thrown from the failing request I'm guessing you'll see it's a 401 unauthorized related to using an invalid token.
Edit:
Disconnecting your app (as described in your comment below) has the same effect as deleting your auth token from developer.vimeo.com.
Also, VimeoUpload accepts a hardcoded auth token (as you see from the README and your code sample). It will not automatically re-authenticate, probably ever.
If you'd like to handle authentication in your app check out VimeoNetworking or VIMNetworking. Either of those libraries can be used to create a variety of authentication flows / scenarios. Still, if a logged in user disconnects or deletes their token, you will need them to deliberately re-authenticate (i.e. you will need to build that flow yourself). In that case, the user has explicitly stated that they don't want the app to be able to access information on their behalf. It would go against our security contract with them to automatically re-authenticate somehow.
Does that make sense?