How to initialize Sign Client of WalletConnect (Android SDK) - android

I have following problem. I just can't figure out how to initialize WalletConnect and connect to Metamask on Android. I always get following exception.
java.lang.NoSuchMethodError: No interface method getInitializationErrorsFlow()Lkotlinx/coroutines/flow/Flow; in class Lcom/walletconnect/android/internal/common/model/JsonRpcInteractorInterface;
My code looks as follows:
val projectId = "15f2b4ae8bb12dsd3d267ce6441d5a9d" // I got the Project ID from https://cloud.walletconnect.com/
val relayUrl = "relay.walletconnect.com"
val serverUrl = "wss://$relayUrl?projectId=$projectId"
val connectionType = ConnectionType.AUTOMATIC
val appMetaData = Core.Model.AppMetaData( // <-- What data should be entered here?
name = "Metamask",
description = "Description",
url = "Wallet Url", // How can I get the wallet url?
icons = listOf(""),
redirect = "kotlin-wallet-wc:/request"
)
CoreClient.initialize(relayServerUrl = serverUrl, connectionType = connectionType, application = application, metaData = appMetaData)
val init = Sign.Params.Init(CoreClient)
SignClient.initialize(init, onError = { error ->
})

Are you calling all initialize methods inside the Application onCreate() method? We have a demo wallet to showcase how it should be done here

enter code here
wc:a593bc04-32b5-4e25-aaec-9e2c247e868a#1?bridge=https%3A%2F%2Fv.bridge.walletconnect.org&key=be7212e692f047b39425b0fe88d805582ac29aa76ccb893d5c0cdef8845dc3c3

All the answers are from this tutorial: Connect a iOS or Android DApp to Web3 Wallet. I strongly recommend reading it.
1. "What data should be entered here?":
It's the data about your DApp, it allows the end user to recognize and decide to grant you rights when his wallet asks for it.
Here is a simple example:
private val metaData = Session.PeerMeta(
name = "nfscene",
url = "nfscene.com",
description = "nfscene WalletConnect demo"
)
2. "How can I get the wallet URL?"
You need to understand that the end-user can choose his wallet. So you can't force the wallet to be used. Knowing what Wallet the user use is not your concern as the transactions are sent through the Wallet Connect bridge. If you only want to allow the use of MetaMask you should directly use the MetaMask API.

you using 2.0.0?
it was fixed in 2.1.0.

Related

Add extra information to Paypal checkout flow using Braintree Drop-inAndroid sdk

It is possible to show list of items in the cart and total amount in the checkout page?
Im using braintree dropin i followed the documentation
This my code so far to build the dropin request, unlickely i don't see any required extra info
val billingAddress = ThreeDSecurePostalAddress()
.givenName("Antonio")
.surname("Ianniello")
.phoneNumber("341908570")
.streetAddress("")
.extendedAddress("")
.locality("Italy")
.region("IT")
.postalCode("80038")
.countryCodeAlpha2("EU")
val additionalInformation = ThreeDSecureAdditionalInformation()
.accountId("account-id")
val threeDSecureRequest = ThreeDSecureRequest()
.amount("100.00")
.versionRequested(ThreeDSecureRequest.VERSION_2)
.email("a.ianny#paypal.com")
.mobilePhoneNumber("341908570")
.billingAddress(billingAddress)
.additionalInformation(additionalInformation)
var paypalRequest = PayPalRequest()
.displayName(PlaceDetailsActivity.selectedBeach.tenantName)
.currencyCode("EUR")
.lineItems(
listOf<PayPalLineItem>(
PayPalLineItem(
PayPalLineItem.KIND_DEBIT,
"Past",
"1",
"20"
)
)
)
val dropInRequest = DropInRequest()
.paypalRequest(paypalRequest)
.collectDeviceData(true)
.requestThreeDSecureVerification(true)
.threeDSecureRequest(threeDSecureRequest)
.clientToken(clientToken)
Thanks a lot for your help!
The Drop-In UI is a form for collecting payment information only, it does not collect checkout-specific fields.
To supply the additional information that is suggested for 3D Secure 2 with a Drop-In integration, you'll need to create your own form to collect this information from the user, and then add that data to a ThreeDSecurerequest object.
For more information, contact Braintree Support

Unable to load config.js

I am using the Jitsi Flutter plugin in conjunction with 8x8's Jitsi-as-a-Service offering to integrate video calls into my mobile app.
Immediately after joining a meeting, the call ends and Jitsi closes. The logs indicate that the underlying Jitsi Meet SDK is unable to fetch config.js from 8x8:
E/JitsiMeetSDK(10937): [features/base/lib-jitsi-meet] Failed to load config from https://8x8.vc/vpaas-magic-cookie-<tenantID>/hello-world/config.js?room=vpaas-magic-cookie-<tenantID>hello-world Error(Error){"message":"loadScript error: undefined","stack":"index.android.bundle:538:817\np#index.android.bundle:284:423\nindex.android.bundle:284:1740\np#index.android.bundle:284:423\nn#index.android.bundle:284:898\nindex.android.bundle:284:1047\nf#index.android.bundle:111:155\nindex.android.bundle:111:882\ny#index.android.bundle:117:661\nC#index.android.bundle:117:1025\ncallImmediates#index.android.bundle:117:3100\ncallImmediates#[native code]\nvalue#index.android.bundle:36:3247\nindex.android.bundle:36:1283\nvalue#index.android.bundle:36:2939\nvalue#index.android.bundle:36:1253\nvalue#[native code]\nvalue#[native code]"}
I/JitsiMeetSDK(10937): [features/overlay] The conference will be reloaded after 19 seconds.
D/JitsiMeetSDK(10937): ExternalAPI Sending event: CONFERENCE_TERMINATED with data: { NativeMap: {"url":"https://8x8.vc/vpaas-magic-cookie-<tenantID>/hello-world/vpaas-magic-cookie-<tenantID>hello-world","error":"Error: loadScript error: undefined"} }
E/ThemeUtils(10937): View class com.facebook.react.views.text.ReactTextView is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant).
I/chatty (10937): uid=10179(com.example.app) identical 1 line
E/ThemeUtils(10937): View class com.facebook.react.views.text.ReactTextView is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant).
D/JITSI_MEET_PLUGIN(10937): JitsiMeetPluginActivity.onConferenceTerminated: {error=Error: loadScript error: undefined, url=https://8x8.vc/vpaas-magic-cookie-<tenantID>/hello-world/vpaas-magic-cookie-<tenantID>hello-world}
D/JITSI_MEET_PLUGIN(10937): JitsiMeetEventStreamHandler.onConferenceTerminated
I/JitsiMeetSDK(10937): Conference terminated: {error=Error: loadScript error: undefined, event=onConferenceTerminated, url=https://8x8.vc/vpaas-magic-cookie-<tenantID>/hello-world/vpaas-magic-cookie-<tenantID>hello-world}
I/JitsiMeetSDK(10937): [features/base/connection] No connection found while disconnecting.
I followed the official 8x8 JaaS docs on how to configure Jitsi in my app:
_joinMeeting(String token, String userName) async {
FeatureFlag featureFlag = FeatureFlag();
featureFlag.welcomePageEnabled = false;
// ...
featureFlag.resolution = FeatureFlagVideoResolution.HD_RESOLUTION;
var options = JitsiMeetingOptions()
..serverURL = "https://8x8.vc"
..room = "vpaas-magic-cookie-<tenantID>/hello-world"
..subject = "Hello World"
..token = token
..userDisplayName = userName
..audioOnly = false
..audioMuted = true
..videoMuted = true
..featureFlag = featureFlag;
await JitsiMeet.joinMeeting(options, roomNameConstraints: Map());
}
It works flawlessly with the public meet.jit.si servers but does not with 8x8's JaaS offering. What am I missing?
Using 8x8's JaaS offering with the Jitsi Flutter plugin
TL;DR: Set the full URL of your 8x8 meeting as the room name.
If you follow the official 8x8 Jaas docs, you will likely end up with Jitsi Flutter being unable to load config.js from the 8x8 server.
This forum comment hints that one can join 8x8 meetings via the official Jitsi Meet app from the App Store by using the full 8x8 meeting URL as the room name.
As a matter of fact, this not only works for the official app, but also for the Jitsi Flutter plugin. Using the configuration below you should be able to connect to a meeting room on your 8x8 tenant. Please make sure to disable any room name constraints by passing an empty map to joinMeeting, otherwise Jitsi Flutter will reject your room name!
_joinMeeting(String token, String userName) async {
FeatureFlag featureFlag = FeatureFlag();
featureFlag.welcomePageEnabled = false;
// ...
featureFlag.resolution = FeatureFlagVideoResolution.HD_RESOLUTION;
var options = JitsiMeetingOptions()
..serverURL = "https://8x8.vc"
..room = "https://8x8.vc/vpaas-magic-cookie-<tenantID>/<roomName>"
..subject = "Hello World"
..token = token
..userDisplayName = userName
..audioOnly = false
..audioMuted = true
..videoMuted = true
..featureFlag = featureFlag;
await JitsiMeet.joinMeeting(options, roomNameConstraints: Map());
}
Hope this saves you some time.

iOS Stripe - Get card token without ephemeral key?

When implementing Stripe in Android there is CardInputWidget which gives you a Card object, then you get a token from Stripe API using that card and finally you send that token to your server, which makes the charge.
When implementing Stripe in iOS I can see that the workflow is quite different. The server needs to have an API endpoint to provide Stripe ephemeral key. Is there any way to do it like in Android workflow - without ephemeral key?
let stripeCard = STPCardParams() /// Declare Stripe Payment Function
stripeCard.name = "Card Name" // you can enter Card Owner name which is displayed in card
stripeCard.number = "Card number" //You can enter card Number which is displayed in Card
stripeCard.expMonth = "ExpireMonth" // enter expire Month which is displayed in Card
stripeCard.expYear = "ExpireYear" // enter expire year which is displayed in Card
stripeCard.cvc = "CVV" // enter CVV which is displayed in Card
//after check card valid or not from below method
if STPCardValidator.validationState(forCard: self.stripeCard) == .valid
{
// the card is valid.
print("Valid card")
STPAPIClient.shared().createToken(withCard: self.stripeCard, completion: { (token, error) -> Void in
if error != nil {
print(error ?? "")
return
}
print(token!)
// call your php Api Pass token id which is given bellow link PHP API link
APICallResponse.shared.getStripePayment(arrUserLoginDetails: self.arrStripePayement,vc:self, completion: {data in
self.SkripePayment = data
})
}
}
You can take reference of PHP API from given link
Stripe payment with php
Yes, absolutely, you can develop with Stripe's iOS SDK without using their pre-built UI or ephemeral key method.
You can use your own form or the STPPaymentCardTextField class, create a STPCardParams instance, and then create a STPToken from that which you can send off to your backend.
STPCardParams *cardParams = [[STPCardParams alloc] init];
cardParams.number = #"4242424242424242";
cardParams.expMonth = 10;
cardParams.expYear = 2020;
cardParams.cvc = #"345";
[[STPAPIClient sharedClient] createTokenWithCard:cardParams completion:^(STPToken *token, NSError *error) {
...
}
}];
See https://stripe.com/docs/mobile/ios/custom#stpapiclient--stpcardparams for more.

Error launching browser in Google.Apis.Auth.OAuth2.LocalServerCodeReceiver on Android

I'm trying to authenticate an end-user in an android app written in C# (Xamarin.Android).
I decided to try and use NuGet package Google.Apis.Oauth.v2 which seems to expose an easy to use Oauth client.
LocalServerCodeReceiver.ReceiveCodeAsync throws the following:
I get System.NotSupportedException:"Failed to launch browser with https://XXX.auth.XXX.amazoncognito.com/login?response_type=token&client_id=XXX&redirect_uri=https%3A%2F%2Fwww.google.com&scope=profile%20openid%20email for authorization. See inner exception for details."
and it has an inner exception of System.ComponentModel.Win32Exception:"Cannot find the specified file"
Code:
var clientSecret = new Google.Apis.Auth.OAuth2.ClientSecrets();
clientSecret.ClientId = ...
clientSecret.ClientSecret = ...
var initializer = new Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.Initializer(
"https://XXX.auth.XXX.amazoncognito.com/login",
"https://XXX.auth.XXX.amazoncognito.com/login");
initializer.Scopes = new List<string> {"profile", "openid", "email"};
initializer.ClientSecrets = clientSecret;
var flow = new Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow(initializer);
var authCodeRequestURL = flow.CreateAuthorizationCodeRequest("https://www.google.com");
authCodeRequestURL.ResponseType = "token";
var uri = authCodeRequestURL.Build();
var cancellationTokenSource = new System.Threading.CancellationTokenSource();
var codeReceiver = new Google.Apis.Auth.OAuth2.LocalServerCodeReceiver();
var task = codeReceiver.ReceiveCodeAsync(authCodeRequestURL, cancellationTokenSource.Token);
Do I need to ask for a specific permission in the application manifest?
Instead of redirecting to www.google.com, I've heard you can redirect to an app, I'm not really sure how to do that, is it http://my_app_package_name or http://my_app_title, something else?
Is it possible not to rely on that library for launching the browser and instead get the RequestUri and start an Activity, if so how will the app become aware the end-user completed the SignIn process and how will the app retrieve the token?
Sorry, but Google.Apis.Oauth.v2 does not support Xamarin, and there's no simple way to get it working.
Unfortunately no Google.Apis.* packages currently support Xamarin.
You might find the Xamarin.Auth package does what you want?
I've figured out how to redirect to an app after authentication in the browser completes.
It's called a "Deep Link" and it's documented at enter link description here, essentially you need to declare an IntentFilter on your Activity, which registers with the Android OS that if someone clicks or an page redirects to a specific URI, your app gets called. The token that's appended to the URI can then be read inside your app.

Java based Google App Engine, Android and authentication oauth2

Authentication and app engine, there is a lot to be read about it, but a lot seems to be outdated!
Even the google pages https://developers.google.com/appengine/docs/java/endpoints/consume_android#making-authenticated-calls
Here, they talk about 'GoogleAccountCredential.usingAudience', but nowadays, you should use GoogleAuthUtil (as far as I know, please correct me if I'm wrong).
I am trying to set up an app engine as a backend to my Android app (and in future, my iOS app).
I am using Android Studio, used the 'new module' and chose app engine with cloud messaging there.
I created a simple endpoint, and have a function there, here is some code:
public class ReviewEndpoint {
// Make sure to add this endpoint to your web.xml file if this is a web application.
private static final Logger LOG = Logger.getLogger(ReviewEndpoint.class.getName());
/**
* This method gets the <code>Review</code> object associated with the specified <code>id</code>.
* #param id The id of the object to be returned.
* #return The <code>Review</code> associated with <code>id</code>.
*/
#ApiMethod(name = "getReview")
public Review getReview(#Named("id") Long id) {
// Implement this function
Review r = new Review();
r.setData("test!");
As you can see, this is nicely generated by Android Studio. I implemented some stuf like creating the 'review' object and return it at the end.
On the Android side, I can do this:
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null);
ReviewEndpoint ep = b.build();
Review review = ep.getReview(1L).execute();
data = review.getData();
and yes, I get 'test!' :)
Now, I want to have this authenticated. I want to know which user wrote what, so I thought I am going to use GMail account and Facebook later.
Here I'm stuck. I am able to get a token from the user on Android:
token = GoogleAuthUtil.getToken(MainScreenActivity.this, mAccount.name, "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile");
then you are able to add this token as credential to the request:
Credential cr = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(token);
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), cr);
Then in the app engine I tried to get the user info, but how?
Will it be supplied as 'bearer'? How do I get this bearer token? Should I then do API request to get the data on the server?
this does not work:
OAuthService service = OAuthServiceFactory.getOAuthService();
try {
User user = service.getCurrentUser();
can anyone give me a heads up?
So finally, today, I found out how to do it! I had questions on Stackoverflow on this before and never had an answer, but these to sites gave me the answer:
https://developers.google.com/appengine/docs/java/endpoints/auth
https://developers.google.com/appengine/docs/java/endpoints/consume_android
The first shows what needs to be done on the app engine side. The second page will tell you how to get the credentials. I was quite close. I am not sure if the adjusting of the build.gradle file mentioned in the second link is necessary. What I added to the App Engine:
#Api(name = "reviewEndpoint", version = "v1", ...<<some more stuff here >>
scopes = {Constants.EMAIL_SCOPE},
clientIds = {Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID},
audiences = {Constants.ANDROID_AUDIENCE})
and then get the credentials:
// Initialize the scope using the client ID you got from the Console.
final String scope = "server:client_id:" + Constants.WEB_CLIENT_ID;
credential = GoogleAccountCredential.usingAudience(activity,scope);
You have to add the e-mail address of the user:
credential.setSelectedAccountName("some-mail-address#gmail.com");
you can get the e-mail address using the account picker (also example shown when you follow the link)
and next. you do a call to the endpoint, using the credential, I think Play Services will validate the user, because if I use an e-mail that is not logged in on the device, it will not work. The following code will throw an GoogleAuthIOException :
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), id_token);
ReviewEndpoint ep = b.build();
Review review;
review = ep.getReview(1L).execute();
for testing, I've put the e-mail address I get at the server side as a string in the review object, and there it gave me the e-mail address instead of the user object being null. Ow! I forgot to tell you, you need a user argument on the app engine side. Even though you do not see the 'user' argument in the 'getReview' call above, it will be added by App Engine.
So this is how my getReview looks now:
#ApiMethod(name = "getReview")
public Review getReview(#Named("id") Long id, User user) {
// Implement this function
Review r = new Review();
r.setData("user == " + (user == null ? "NULL " : user.toString()));
Hope this will help someone

Categories

Resources