WalletConnect with Ethersjs - javascript

is anyway to use walletconnect with etherejs ?
the demos are nice but they are with wagmi
i cant port all project from etherjs to wagmi
i need this feature this button connect disconect and possibility to use only few networks/chainids
import { arbitrum, mainnet, polygon } from "wagmi/chains";
https://docs.walletconnect.com/2.0/web3modal/react/installation
i this this exactly but with ETHERSJS
const { provider } = configureChains(chains, [
walletConnectProvider({ projectId: "<YOUR_PROJECT_ID>" }),
]);
const wagmiClient = createClient({
autoConnect: true,
connectors: modalConnectors({ appName: "web3Modal", chains }),
provider,
});
// Web3Modal Ethereum Client
const ethereumClient = new EthereumClient(wagmiClient, chains);

I found official example for WalletConnect v2 integration with Ethers.js
See https://github.com/WalletConnect/web-examples/blob/main/dapps/react-dapp-v2-with-ethers/src/contexts/ClientContext.tsx
Bad thing is that it's more complex than one with Wagmi. You have to connect lot of WalletConnect events to keep session info up to date, or to reset connection state.
Also official example (ClientContext.tsx) is IMO overusing React state which is not ideal. Would be nice to have official Ethers wrapper (not React, or other UI library dependent).
But it is definitely useful example to make Ethers integration work.

Related

Executing code pre and post mutation graphql neo4j apollo server

I'm just getting started with GraphQL and I've worked mostly with featherjs to build REST APIs so far. There's the concept of hooks to run code before or after interacting with a service. I wanted to know if there's a way to achieve something similar in a graphql setup.
The specific stack I'm using is neo4j and graphql, express, and apollo server. Since neo4j has a graphql module, I'm not writing the general queries and mutations, just the model types.
For a concrete example, below is a basic API server. It's put together using docker compose and has users and applications. I would like to in general be able to run arbitrary code before or after a mutation with access to the model being modified. Things like more complex validation before, or side effects after.
Those things could be here, for example, before changing the state of an application to declined, make sure that a note is added. Or after changing the state to approved, send an email to the applicant.
I'm not sure how or where to implement this kind of thing, any help is appreciated! Or also if I'm thinking about graphql wrong and there's a better way of doing what I'm trying to do.
Thanks!
import http from 'http';
import express from 'express';
import neo4j from 'neo4j-driver';
import {Neo4jGraphQL} from '#neo4j/graphql';
import {gql, ApolloServer} from 'apollo-server-express';
import {ApolloServerPluginDrainHttpServer} from 'apollo-server-core';
const typeDefs=gql`
type User {
email: String!
applications: [Application!] #relationship(type: "APPLICANT", direction: OUT)
}
type Application {
user: User! #relationship(type: "APPLICANT", direction: IN)
state: String!
note: String
}
`;
const driver=neo4j.driver(
'neo4j://neo4j:7687',
neo4j.auth.basic('neo4j', 'password')
);
const {schema}=new Neo4jGraphQL({typeDefs, driver});
(async ()=>{
const app=express();
const server=http.createServer(app);
const apollo=new ApolloServer({
schema,
plugins: [ApolloServerPluginDrainHttpServer({httpServer: server})]
});
await apollo.start();
apollo.applyMiddleware({app});
await new Promise(r=>server.listen({port: 4000}, r));
console.log('GraphQL server listening at '+apollo.graphqlPath);
})();

How to create a basic client to use GraphQL subscriptions via websockets

I'm trying to create a basic chat-like app just for the sake of learning a few things.
I have set up a basic graphql server to handle connecting a user, and let them add a message. Now I'm trying to add some mechanism so that every user can see each others' messages added in real time. I'm new to GraphQL but it would seem subscriptions are what I should use.
Here's my server index.ts:
import { createServer } from 'http';
import jwt from 'jsonwebtoken';
import mongoose from 'mongoose';
import resolvers from 'modules/resolvers';
import typeDefs from 'modules/type-defs';
import { ApolloServer } from 'apollo-server-express';
import cookieParser from 'cookie-parser';
import express from 'express';
import cors from 'cors';
const PORT = 4000;
const getUser = (token: string) => {
// ...
};
const server = new ApolloServer({
context: ({ req, res }) => {
const token = req.cookies.jwt;
const currentUser = getUser(token);
return { currentUser, req, res };
},
resolvers,
subscriptions: {
onConnect: async (connectionParams, webSocket, context) => {
console.log(`Subscription client connected using Apollo server's built-in SubscriptionServer.`)
},
onDisconnect: async (webSocket, context) => {
console.log(`Subscription client disconnected.`)
},
},
typeDefs,
});
const app = express();
const httpServer = createServer(app);
app.use(cors({ credentials: true, origin: 'http://localhost:3000' }));
app.use(cookieParser());
server.applyMiddleware({ app, cors: false });
server.installSubscriptionHandlers(httpServer);
httpServer.listen(PORT, () => {
console.log(`Server ready at http://localhost:${PORT}${server.graphqlPath}`);
console.log(`Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`);
});
mongoose.connect('mongodb://127.0.0.1:27017/irc', {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
});
What I'm trying to do is set up something as simple as possible on the client side (javascript/react) without having to rely on a lib like apollo-client.
I managed to use simple fetch calls to send queries/mutations and was expecting to be able to use subscriptions in a "simple" way too. Apollo-client seems over complicated for what I'm trying to do and I'd like to understand how it actually works - but every tutorial on subscriptions seem to use this lib...
I don't really understand what my server is actually doing regarding subscriptions, and I thought I'd configured it to listen to websockets connections but I'm not so sure anymore.
I tried sending a basic message just to see what would happen:
const ws = new WebSocket('ws://localhost:4000/graphql');$
ws.onopen = event => {
ws.send('Lorem ipsum dolor sit amet.');
};
... but even though my chrome's network tab seems to indicate that everything went fine, my server does not seem to care about my message since nothing gets logged.
Could someone please explain if it's possible to use basic web sockets to use apollo-server's subscriptions? And how?
Thanks
Apollo Server and Apollo Client both use subscriptions-transport-ws under the hood to handle subscriptions. subscriptions-transport-ws uses WebSocket as a transport for exchanging messages between the server and the client. These messages have a specific format used by the library -- in order to use only WebSocket on the client-side, you'd have to send the same sort of messages.
You could inspect the source code to determine what sort of messages are being sent and when. The better option, though, would be to create an instance of SubscriptionClient and utilize its methods. Since usage of the library isn't particularly well documented, you'd have to stumble your way through but it should be possible.
If you're new to GraphQL, though, you should stick with Apollo Client since it's documentation is fairly good (see here) and subscriptions can be pretty complicated to set up, especially once you add authentication.

How to use Graphql Vue Apollo on older IOS / older browser?

I just realize and noticing that my vue app doesn't work well on some older browsers (ios 9 for example). I used the vue-apollo to get data from graphql api using django graphene , but it doesn't event get called on the first load when i debug it.
Previously i get error like "fetch is not found globally", but then i already fix it by adding "unfetch" to the ApolloClient config. But i still can't see on xhr network the api get called. I haven't try with isomorphic-fetch
Here's my code for the apollo client config:
// src/utils/graphql.js
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import fetch from 'unfetch'
export default new ApolloClient({
// Provide the URL to the API server.
link: new HttpLink({ uri: '/api/', fetch: fetch }),
// Using a cache for blazingly
// fast subsequent queries.
cache: new InMemoryCache(),
connectToDevTools: true
});
and i specify it like so in the main.js
import apolloClient from '../utils/graphql'
import VueApollo from 'vue-apollo'
Vue.use(VueApollo);
Vue.config.silent = true
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
$loadingKey: "loading"
}
})
This is example of the apollo that i use inside the main.js as well using the smart query:
apollo: {
currentUser: {
query: GET_LOGGED_USER,
skipQuery() {
return this.skipUser
}
}
}
How can i make it work on ios 9 / any older browser?
Ok, after debugging it for two days, I finally found out the issue. So it turns out that i need to add and configure babel/polyfill as well in order to make it works, and add it to the entry point of my app.
Hope everyone who has the same issue can learn from my mistake lol

Auth0 authentication with Gridsome server side rendering breaks with window is undefined

I've implemented the auth0 Vuejs according to their tutorial with Gridsome, and it worked fine in develop.
However, when I run gridsome build the build fails because window is undefined in a server context.
I've found a few issues in Auth0-js lib that claim that Auth0 should only be used in client side, however, due to the way Gridsome works, I can't seem to find a way to only load the Auth0-js in client side.
Gridsome has main.js where I would add plugins, and in there, I define the routing for authentication.
Main.js
import AuthServicePlugin from '~/plugins/auth0.plugin'
import auth from '~/auth/auth.service'
export default function (Vue, { router, head, isClient }) {
...
Vue.use(AuthServicePlugin)
//Handle Authentication
router.beforeEach((to, from, next) => {
if (to.path === "/auth/logout" || to.path === "/auth/callback" || auth.isAuthenticated()) {
return next();
}
// Specify the current path as the customState parameter, meaning it
// will be returned to the application after auth
auth.login({ target: to.path });
})
Based on a Gatsbyb.js auth0 implementation tutorial, I've tried to exlude auth0-js from webpack loading with null-loader
gridsome.config.js
configureWebpack: {
/*
* During the build step, `auth0-js` will break because it relies on
* browser-specific APIs. Fortunately, we don’t need it during the build.
* Using Webpack’s null loader, we’re able to effectively ignore `auth0-js`
* during the build. (See `src/utils/auth.js` to see how we prevent this
* from breaking the app.)
*/
module: {
rules: [
{
test: /auth0-js/,
use: 'null-loader',
},
],
},
I would love to get some ideas about how to include and load Auth0 only in client side context with Gridsome
I had the same problem with using Firebase Authentication with Gridsome.
It seems that code in the created() lifecycle hook gets executed in the Gridsome build process (which is a server environment), but code in the mounted() lifecycle hook only executes in the browser!
The solution was to put all the code that should only run in the client in the mounted lifecycle hook.
mounted() {
// load the `auth0-js` here
...
}
In my instance (with Firebase Auth) this was the solution:
In the Default Layout component:
const app = import("firebase/app");
const auth = import("firebase/auth");
const database = import("firebase/firestore");
const storage = import("firebase/storage");
Promise.all([app, auth, database, storage]).then(values => {
// now we can access the loaded libraries 😍!
});
}

Firestore arrayUnion

I'm building a basic CRUD app with vue.js and firebase. I'm trying to build out a favorites functionality and have ran into a persistent problem storing the data.
When a using clicks the add to favorites button I'm attempting to add the document id to an array in a "user profile" document. Here's the code:
export function addNewUserAction (type, key, userID){
console.log(userID);
console.log(key);
firebase.firestore().collection('userActions').add({
type: type,
listing: key,
user: userID,
time: Date.now()
})
if(type === 'favorite'){
var sendfav = db.collection('userProfiles').doc(userID).update({
favs: firebase.firestore.FieldValue.arrayUnion(key)
});
}else if(type === 'xout'){
var sendxout = db.collection('userProfiles').doc(userID).update({
xouts: firebase.firestore.FieldValue.arrayUnion(key)
});
}else{
console.error(type + " is not a user action");
}
}
I get the following error in the console:
Uncaught TypeError: Cannot read property 'arrayUnion' of undefined
at addNewUserAction
I have firebase and the db ref imported, and have ran a bogus .set() through each reference to confirm they are pointing at the right spots. I also already have the arrays created in 'userProfile' document.
The firebase install is fresh, like last week fresh, so I should have the function in my build.
Seems that arrayUnion is just not working. Any ideas? The other firestore functions are workin so I'm not sure. Am I blatenly missing something? Thanks
If you are using the Admin SDK
I was having some random errors similar to this, among others as I was experimenting. It turns out it was because I was using firebase admin sdk which requires a slight change compared to the web SDK documentation. If you are using firebase admin, replace
firebase.firestore.FieldValue.arrayUnion(...
with
admin.firestore.FieldValue.arrayUnion(...
I had the same issue...
This would not work
import { fireStore } from '../../firebase';
....
fireStore.collection("users").doc(props.uid).update({
points: fireStore.FieldValue.arrayUnion({value: pointObj.value, reason: pointObj.reason})
});
I changed the import and used the exact code from the Firebase Docs.
This works fine.
import * as firebase from 'firebase';
....
fireStore.collection("users").doc(props.uid).update({
points: firebase.firestore.FieldValue.arrayUnion({value: pointObj.value, reason: pointObj.reason})
});
Hope that helps.
Just wanted to update this. I was able to get this working by importing firebase the following way:
`import firebase from "firebase/firebase";`
I think my issue before was several problems, the first primarily was not having the correct version. I just recently updated to 5.8.4 which completely broke my app. I tried the above as a possible solution and it got my app working again. That led me to try it on with arrayUnion and it worked. Hopefully thats helpful to someone. Thanks all for the help.
Update 10/11/19
So I wanted to add another update to this in case someone new to firebase is chasing their tail with this as I have been.
So the solution I included above works because it uses the entire firebase SDK package ('firebase/firebase') which is fine, however you will importing the entire firebase package which is not ideal. You constantly see an alert in your console that you're using the development SDK
If you're trying to optimize your app and only import the firebase packages you need ( i.e. auth, datatbase, etc.) you need to import the firebase app object from 'firebase/app' then import the required packages. The key is to import as an object as the firebase docs call for:
import * as firebase from 'firebase/app';
Import 'firebase/auth'
If you use:
import firebase from 'firebase/app' this will not work.
Hope that helps someone. I know it's probie stuff but it stumped me for a while in my learning curve.
Firestore - Pass Array To arrayUnion()
let myArray = ["1", "2", "3"];
docRef.update({
test: firebase.firestore.FieldValue.arrayUnion.apply(this, myArray)
});
This worked for me^
For Vue.js Developers
I have created a folder named firebase in src folder, then i have created a file named init.js in firebase folder
init.js
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
// Your Firebase Config
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// utils
const db = firebase.firestore();
const auth = firebase.auth();
export { db, auth, firebase };
Now use them in whichever components you need.
Just by,
import { firebase, auth, db } from "#/firebase/init.js";
Now You can use firebase without any Errors
db.collection("users") // Collection Name
.doc(userId) // Document in Collection indexed userId
.update({
friends: firebase.firestore.FieldValue.arrayUnion(auth.currentUser.uid)
})
// friends is the array collection in firestore
Thats It

Categories