MetaMask - RPC Error: Invalid parameters: must provide an Ethereum address - javascript

I am trying to integrate with DyDx Protocol, and trying to perform some action on the PrivateAPI:
const client: DydxClient = new DydxClient(
DYDX_HOST,
{
networkId: 5,
web3: new Web3(window.ethereum),
},
);
and calling the APICredentials call, it is failing:
client.onboarding.recoverDefaultApiCredentials(
address,
).then((response) => {
console.log("response for api keys", response)
});
Below is the error:
"{
"code": -32602,
"message": "Invalid parameters: must provide an Ethereum address.",
"stack": "Error: Invalid parameters: must provide an Ethereum address.\n at new r (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:322950)\n at i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:325706)\n at Object.invalidParams (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:326213)\n at p (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-0.js:10:31397)\n at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-0.js:10:29445\n at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:38021\n at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:38404\n at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:37125\n at new Promise (<anonymous>)\n at a._runMiddleware (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:36782)\n at a._runAllMiddleware (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:36688)\n at async chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:35360"
}
at new r (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:322950)
at i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:325706)
at Object.invalidParams (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:326213)
at p (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-0.js:10:31397)
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-0.js:10:29445
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:38021
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:38404
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:37125
at new Promise (<anonymous>)
at a._runMiddleware (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:36782)
at a._runAllMiddleware (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:36688)
at async chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:19:35360"
I have already tried to convert the GoreliaTestNet address to checkSum:
const address = Web3.utils.toChecksumAddress(accounts[0]);
But still no luck.

Found the solution, had to add the signing method.
client.onboarding.recoverDefaultApiCredentials(
address,SigningMethod.MetaMask
).then((response) => {
console.log("response for api keys", response)
});

Related

HubspotClient - Update contact by email id is not working

In NodeJS, I'm using "#hubspot/api-client": "^7.1.2".
Created hubspot client using accessToken as follows
const hubSpotClient = new hubspot.Client({ accessToken });
When I try to update the contact using email it's throwing error
Request:
const idProperty = 'email';
const response = await hubSpotClient(store).crm.contacts.basicApi.update(email, idProperty, contact);
Response:
ERROR {
"statusCode": 404,
"body": {
"status": "error",
"message": "Object not found. objectId are usually numeric.",
"correlationId": "71e911d3...",
"context": {
"id": [
"testemail#..."
]
},
"category": "OBJECT_NOT_FOUND"
}
Create contact is working fine with this client but updating by email is not working.
Anything out of place or syntax error in passing the idProperty?
The problem is in your implementation, because it seems like you are not using properly the Hubspot API.
If you check the function signature of the basicApi.update
public async update(contactId: string, simplePublicObjectInput: SimplePublicObjectInput, idProperty?: string, _options?: Configuration): Promise<RequestContext> {
Basically, you need to pass down a contactId, and then a simplePublicObjectInput that is basically an object that represents your update.
Your code should look like this:
import { Client } from "#hubspot/api-client";
const hubspotClient = new Client({ accessToken: YOUR_ACCESS_TOKEN });
const contactID = 1234;
const response = await hubspotClient.crm.contacts.basicApi.update(contactID, {
properties: { email: 'my-new-email#gmail.com' },
})
Keep in mind that Hubspot always tries to follow their same guidelines as their endpoints. If your check the endpoint specification you will see the following:
Think about the Hubspot node client as just an abstraction of some http client, but at the end does exactly the same as the endpoints described in their implementations.
For that reason, in your implementation, Hubspot is returning an appropriated error, since you are not giving the contactId in the first argument, Hubspot is telling you: "Object not found. objectId are usually numeric." Because indeed a Contact ID is numeric and you are using the value of an email --string-- instead.
If you want to "update by email"
I think that there is no direct way to do it, you might need to do a previous search of the contact by email.
You could use the searchApi.
And after getting the id just run the update.
const searchResponse = await hubspotClient.crm.contacts.searchApi.doSearch({
filterGroups: [
{
filters: [
{
value: 'email-to-search#gmail.com',
propertyName: 'email',
operator: 'EQ',
},
],
},
],
sorts: [],
properties: [],
limit: 1,
after: 0,
});
// Off course you need to improve a lot the error handling here and so on.
// This is just an example
const [contactID] = searchResponse.results;
const contactUpdateResponse = await hubspotClient.crm.contacts.basicApi.update(contactID, {
properties: { email: 'my-new-email#gmail.com' },
})
I hope this helps you!
You CAN use email as the idProperty for the hubspot/api-client get contact function, but it only works if you fill in all the other query fields before idProperty, even if they are undefined.
Here is my example of a getContactByEmail as a Google Cloud Function in Node, using the api-client, and it works great!
exports.getContactByEmail = functions.https.onCall(async (data, context) => {
const email = data.email;
const contactId = email;
const properties = ["firstname", "lastname", "company"];
const propertiesWithHistory = undefined;
const associations = undefined;
const archived = false;
const idProperty = "email";
try {
const apiResponse = await hubspotClient.crm.contacts.basicApi.getById(
contactId,
properties,
propertiesWithHistory,
associations,
archived,
idProperty
);
console.log(JSON.stringify(apiResponse.body, null, 2));
return apiResponse.properties;
} catch (error) {
error.message === "HTTP request failed"
? console.error(JSON.stringify(error.response, null, 2))
: console.error(error);
return error;
}
});

Paypal Checkout client integration - Problem with returning order id promise

i have a problem integrating paypals payment gateway. I am using javascript for the client, python for the backend and the checkouts v2 api.
Creating a order on the backend works without trouble, but while waiting for my servers response the createOrder function raises a error:
unhandled_error
Object { err: "Expected an order id to be passed\nLe/</<#https://www.sandbox.paypal.com/smart/buttons?style.layout=vertical&style.color=blue&style.shape=rect&style.tagline=false&components.0=buttons&locale.country=NO&locale.lang=no&sdkMeta=eyJ1cmwiOiJodHRwczovL3d3dy5wYXlwYWwuY29tL3Nkay9qcz9jbGllbnQtaWQ9QWJmSjNNSG5oMkFIU1ZwdXl4eW5lLXBCbHdJZkNsLXpyVXc1dzFiX29TVUloZU01LXNMaDNfSWhuTnZkNUhYSW5wcXVFdm5MZG1LN0xOZ1gmZGlzYWJsZS1mdW5kaW5nPWNyZWRpdCxjYXJkIiwiYXR0cnMiOnt9fQ&clientID=AbfJ3MHnh2AHSVpuyxyne-pBlwIfCl-zrUw5w1b_oSUIheM5-sLh3_IhnNvd5HXInpquEvnLdmK7LNgX&sessionID=e2ea737589_mtc6mtu6mdi&buttonSessionID=de4bfb3626_mtc6mjm6mtk&env=sandbox&fundingEligibility=eyJwYXlwYWwiOnsiZWxpZ2libGUiOnRydWV9LCJjYXJkIjp7ImVsaWdpYmxlIjpmYWxzZSwiYnJhbmRlZCI6dHJ1ZSwidmVuZG9ycyI6eyJ2aXNhIjp7ImVsaWdpYmxlIjp0cnVlfSwibWFzdGVyY2FyZCI6eyJlbGlnaWJsZSI6dHJ1ZX0sImFtZXgiOnsiZWxpZ2libGUiOnRydWV9LCJkaXNjb3ZlciI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJoaXBlciI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJlbG8iOnsiZWxpZ2libGUiOmZhbHNlfSwiamNiIjp7ImVsaWdpYmxlIjpmYWxzZX19…", timestamp: "1593537805136", referer: "www.sandbox.paypal.com", sessionID: "e2ea737589_mtc6mtu6mdi", env: "sandbox", buttonSessionID: "de4bfb3626_mtc6mjm6mtk" }
Error: Expected an order id to be passed
Error: Expected an order id to be passed
12V21085461823829 // ticks in a few seconds later
Console screenshot
The problem seems to be that createOrder does not wait for the promise before raising the error, or that the promise is not given in the correct way. Something like that. Anyways here is the client side code:
paypal.Buttons({
// button styling removed for clarity
createOrder: function() {
// purchase information
var data = {
'track_id': vm.selectedTrack.id,
'lease_id': vm.selectedLease.id,
}
// post req to api with lease and track ids
// create payment on server side
fetch('http://localhost:5000/api/paypal/create-purchase', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(data),
}).then(function(res) {
return res.json();
}).then(function(data) {
console.log(data.order_id)
return data.order_id
})
}
// conatiner element to render buttons in
}).render('#paypal-button');
And the server side:
#app.route('/api/paypal/create-purchase', methods=['POST'])
def paypal_create_purchase():
# cart validation removed for clarity
# create paypal purchase
environment = SandboxEnvironment(client_id=app.config['PAYPAL_PUBLIC'], client_secret=app.config['PAYPAL_PRIVATE'])
client = PayPalHttpClient(environment)
paypal_request = OrdersCreateRequest()
paypal_request.prefer('return=representation')
paypal_request.request_body (
{
"intent": "CAPTURE",
"purchase_units": [
{
"amount": {
"currency_code": "USD",
"value": lease.price
}
}
]
}
)
try:
# Call API with your client and get a response for your call
response = client.execute(paypal_request)
order = response.result
print(order.id)
except IOError as ioe:
print (ioe)
if isinstance(ioe, HttpError):
# Something went wrong server-side
print(ioe.status_code)
# note that it is the same key as on the client
return jsonify(success=True,order_id=order.id)
I found this similar thread, but i dont consider the origin of the error to be the same as in that thread (incorrect json key on client)
Also see this relevant page in the docs which supplies this code:
createOrder: function() {
return fetch('/my-server/create-paypal-transaction', {
method: 'post',
headers: {
'content-type': 'application/json'
}
}).then(function(res) {
return res.json();
}).then(function(data) {
return data.orderID; // Use the same key name for order ID on the client and server
});
}
Damn, just as i was typing out the last part of the post i noticed the error. A missing return before my fetch call. Will leave this up for other people with the same mistake.

Apollo type defs ignored

I've made a basic implementation of ApolloClient:
const gqlClient = new ApolloClient({
connectToDevTools: true,
link: new HttpLink({
uri: "/api",
}),
cache: new InMemoryCache(),
resolvers: {
Group: {
icon: () => "noIcon",
},
},
typeDefs: gql`
extend type Group {
icon: String!
}
`,
});
The only fancy thing is the one resolver and type def - both of which are to support an icon field for groups (an upcoming feature).
I then try to query the server with the following:
gqlClient.query({
query: gql`{
groups {
name
icon
}
}`,
})
.then(console.log);
and get a big 'ol error:
bundle.esm.js:63 Uncaught (in promise) Error: GraphQL error: Cannot query field `icon' on type `Group'.
at new ApolloError (bundle.esm.js:63)
at bundle.esm.js:1247
at bundle.esm.js:1559
at Set.forEach (<anonymous>)
at bundle.esm.js:1557
at Map.forEach (<anonymous>)
at QueryManager../node_modules/apollo-client/bundle.esm.js.QueryManager.broadcastQueries (bundle.esm.js:1555)
at bundle.esm.js:1646
at Object.next (Observable.js:322)
at notifySubscription (Observable.js:135)
Running the same query without asking for icon works perfectly. I'm not quite sure what I'm doing wrong. How can I mock icon and fix this error?
I'm only running Apollo Client - do I need to run Apollo Server to get all of the features? The outgoing request doesn't seem to have any of my type def information, so I'm not sure how the having Apollo server would make a difference.
Handling #client fields with resolvers
gqlClient.query({
query: gql`
{
groups {
name
icon #client
}
}
`,
});

Updating Stripe accounts returns "Error: Stripe: "id" must be a string, but got: object"

I am trying to update a Stripe account to add an external account token to be charged later as shown in the example here.
var stripe = require("stripe")("sk_test_xxxxxxxxxxxxx"),
knex = require("knex")(config);
router.post("/paymentcardinfo",middleware.isLoggedIn,function(req,res){
knex("users.stripe").select("stripe_id_key")
.then((stripeID) => {
stripeID = stripeID[0].stripe_id_key;
console.log("My Stripe ID: "stripeID);
console.log("stripeID var type:", typeof stripeID);
stripe.accounts.update({
stripeID,
external_account: req.body.stripeToken,
}, function(err,acct) {
if(err){
console.log(err);
} else {
console.log("SUCCESS ********",acct);
// asynchronously called
}})
})
.catch((e) => {
console.log(e);
res.redirect("/paymentcardinfo")
});
});
Which returns the following
My Stripe ID: acct_xxxxxxxxxxxxx
stripeID var type: string
[Error: Stripe: "id" must be a string, but got: object (on API request to `POST /accounts/{id}`)]
where acct_xxxxxxxxxxx is the user's stored account ID. Based on the first console.log value, it would appear that stripeID is a string and not an object, which makes me unsure of how to proceed with this error.
Although the documentation specifies
stripe.accounts.update({
{CONNECTED_STRIPE_ACCOUNT_ID},
metadata: {internal_id: 42},
}).then(function(acct) {
// asynchronously called
});`
The following worked for me
stripe.accounts.update(
CONNECTED_STRIPE_ACCOUNT_ID,
{
metadata: {internal_id:42},
}
).then((account) => {
// response to successful action

Mongoose custom type causes 500 internal server error in hapi / rest-hapi

I am using Mongoose in a hapi server with rest-hapi. I have defined a custom type in Mongoose, according to the documentation at http://mongoosejs.com/docs/customschematypes.html. After encountering issues with my own custom type, I also tried the documentation's Int8 example.
With the custom type, an invalid value causes the hapi server to encounter an internal server error, rather than returning a 400 error response. With the built-in string type, an invalid value results in the expected 400 error response.
I've looked at the implementation of the String type, and its cast function throws an error for an invalid value, just like the cast function in my custom type. (Note the example has a comment that says to throw a CastError, but actually throws an Error. I've tried it both ways, with the same result.)
What do I need to do to make my custom type behave the same as the built-in types for invalid values?
Here's a test model the demonstrates the issue:
'use strict';
module.exports = function(mongoose) {
function Int8(key, options) {
mongoose.SchemaType.call(this, key, options, 'Int8');
}
Int8.prototype = Object.create(mongoose.SchemaType.prototype);
Int8.prototype.cast = function(val) {
let _val = Number(val);
if (isNaN(_val)) {
throw new Error('Int8: ' + val + ' is not a number');
}
_val = Math.round(_val);
if (_val < -0x80 || _val > 0x7F) {
throw new Error('Int8: ' + val +
' is outside of the range of valid 8-bit ints');
}
return _val;
};
mongoose.Schema.Types.Int8 = Int8;
const modelName = 'test';
const Types = mongoose.Schema.Types;
const Schema = new mongoose.Schema({
string: {
type: Types.String,
required: true,
},
int8: {
type: Types.Int8,
required: true,
},
});
Schema.statics = {
collectionName: modelName,
routeOptions: {},
};
return Schema;
};
Here's my test file:
'use strict';
const expect = require('chai').expect;
const merge = require('lodash/merge');
describe.only('/test', () => {
describe('POST', () => {
const requestDefaults = {
method: 'POST',
url: '/test',
payload: {},
};
describe('invalid data', () => {
it('should reject missing fields', () => {
const request = merge({}, requestDefaults);
return server.inject(request)
.then(response => {
expect(response)
.to.be.an('object')
.with.property('statusCode', 400);
});
});
it('should reject invalid string', () => {
const request = merge({}, requestDefaults, {
payload: {
string: 7,
int8: 7,
},
});
return server.inject(request)
.then(response => {
expect(response)
.to.be.an('object')
.with.property('statusCode', 400);
});
});
it('should reject invalid int8', () => {
const request = merge({}, requestDefaults, {
payload: {
string: 'hello',
int8: 0xFF,
},
});
return server.inject(request)
.then(response => {
expect(response)
.to.be.an('object')
.with.property('statusCode', 400);
});
});
});
});
});
And here's the test output (with the stacktrace trimmed):
[10:34:16.983] 39140 LOG api/mongoose — Connecting to Database...:
[10:34:16.991] 39140 LOG api/mongoose — URI: `mongodb://127.0.0.1:9001/test`
[10:34:17.013] 39140 LOG api — Initializing Server...
(node:39140) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client
/test
POST
invalid data
✓ should reject missing fields (95ms)
✓ should reject invalid string
[10:34:18.151] 39140 LOG api/test/Create — params({}), query({}), payload({"string":"hello","int8":255})
[10:34:18.181] 39140 ERROR ../../rest-hapi/utilities/handler-helper.js:464:23 api/test/Create — There was an error creating the resource.
[10:34:18.183] 39140 ERROR ../../rest-hapi/utilities/error-helper.js:27:11 api/test/Create — MongooseError:
[10:34:18.183] 39140 ERROR ../../rest-hapi/utilities/error-helper.js:27:11 api/test/Create — at ValidationError (/Users/chipmunk/git/magic-wand-api/node_modules/mongoose/lib/error/validation.js:27:11)
[10:34:18.183] 39140 ERROR ../../rest-hapi/utilities/error-helper.js:27:11 api/test/Create — at model.Document.invalidate (/Users/chipmunk/git/magic-wand-api/node_modules/mongoose/lib/document.js:1609:32)
[10:34:18.183] 39140 ERROR ../../rest-hapi/utilities/error-helper.js:27:11 api/test/Create — at model.Document.set (/Users/chipmunk/git/magic-wand-api/node_modules/mongoose/lib/document.js:758:10)
...
[10:34:18.186] 39140 ERROR ../../rest-hapi/utilities/error-helper.js:60:11 api/test/Create — TypeError: Boom.serverTimeout is not a function
[10:34:18.186] 39140 ERROR ../../rest-hapi/utilities/error-helper.js:60:11 api/test/Create — at Object.formatResponse (/Users/chipmunk/git/magic-wand-api/node_modules/rest-hapi/utilities/error-helper.js:43:27)
...
1) should reject invalid int8
2 passing (1s)
1 failing
1) /test POST invalid data should reject invalid int8:
AssertionError: expected { Object (raw, headers, ...) } to have property 'statusCode' of 400, but got 500
+ expected - actual
-500
+400
at test/api/test.js:54:21
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:208:7)
error Command failed with exit code 1.1
I figured out the answer to my question.
rest-hapi uses Joi to validate the document before passing it to Mongoose. rest-hapi converts the Mongoose model to a Joi model by mapping the Mongoose types to corresponding Joi types. Of course, it doesn't recognize my custom type, so it has Joi accept any value for that field.
So, for a field with the standard String type, rest-hapi rejects an invalid value in the initial validation step and returns a 400 error response. For a field with a custom Mongoose type, rest-hapi accepts it in the initial validation step, but mongoose rejects it, and rest-hapi returns a 500 error response.
I haven't yet thought about how to resolve this difference in behavior.

Categories