Skip to content

Commit

Permalink
feat: web3 headless provider and wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
nklomp committed Aug 25, 2023
1 parent c69cf9e commit 00fc40a
Show file tree
Hide file tree
Showing 14 changed files with 241 additions and 334 deletions.
64 changes: 32 additions & 32 deletions packages/ssi-express-support/__tests__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const STRATEGY = env('OIDC_STRATEGY_NAME', PREFIX) ?? 'oidc'
console.log(`Starting OIDC RP API for env '${ENVIRONMENT}/${process.env.NODE_ENV}', issuer: ${issuerUrl} with strategy ${STRATEGY}`)

async function init() {
const oidcIssuer = await oidcDiscoverIssuer({issuerUrl})
const oidcIssuer = await oidcDiscoverIssuer({ issuerUrl })
const devMetadata: ClientMetadata = {
client_id: env('OIDC_CLIENT_ID', PREFIX) ?? 'EnergySHRDev',
client_secret: env('OIDC_CLIENT_SECRET', PREFIX) ?? 'iZDmseeTIpuVFcodqc3cQpJ6gak7xMfa',
Expand Down Expand Up @@ -41,42 +41,42 @@ async function init() {
hostname: env('HOSTNAME', PREFIX) ?? 'localhost',
})

.withMorganLogging()
.withCorsConfigurer(
new ExpressCorsConfigurer().allowOrigin(env('OIDC_FRONTEND_CORS_ORIGIN', PREFIX) ?? 'http://localhost:3001').allowCredentials(true)
)
.withPassportAuth(true)
.withSessionOptions({
secret: env('OIDC_SESSION_SECRET', PREFIX) ?? 'defaultSecretPleaseChange!',
// proxy: true,
resave: false,
saveUninitialized: true,
/*cookie: {
.withMorganLogging()
.withCorsConfigurer(
new ExpressCorsConfigurer().allowOrigin(env('OIDC_FRONTEND_CORS_ORIGIN', PREFIX) ?? 'http://localhost:3001').allowCredentials(true)
)
.withPassportAuth(true)
.withSessionOptions({
secret: env('OIDC_SESSION_SECRET', PREFIX) ?? 'defaultSecretPleaseChange!',
// proxy: true,
resave: false,
saveUninitialized: true,
/*cookie: {
maxAge: (24 * 60 * 60),
httpOnly: false
}*/
})
.build({startListening: false})
})
.build({ startListening: false })

passport.use(
STRATEGY,
new Strategy(
{
client,
passReqToCallback: true,
params: {
scope: 'openid email',
},
},
(req: any, tokenSet: any, userinfo: UserinfoResponse<any, any>, done: any) => {
req.session.tokens = tokenSet
const authInfo = {
...userinfo,
...tokenSet.claims(),
}
return done(null, authInfo)
}
)
STRATEGY,
new Strategy(
{
client,
passReqToCallback: true,
params: {
scope: 'openid email',
},
},
(req: any, tokenSet: any, userinfo: UserinfoResponse<any, any>, done: any) => {
req.session.tokens = tokenSet
const authInfo = {
...userinfo,
...tokenSet.claims(),
}
return done(null, authInfo)
}
)
)
passport.serializeUser(function (user, done) {
done(null, user)
Expand Down
2 changes: 1 addition & 1 deletion packages/ssi-express-support/src/express-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function sendErrorResponse(response: express.Response, statusCode: number

export const jsonErrorHandler = (err: any, req: express.Request, res: express.Response, next: NextFunction) => {
const statusCode: number = 'statusCode' in err ? err.statusCode : 500
const errorMsg = typeof err === 'string' ? err : (err.message ?? err)
const errorMsg = typeof err === 'string' ? err : err.message ?? err
if (res.headersSent) {
console.log('Headers already sent, when calling error handler. Will defer to next error handler')
console.log(`Error was: ${JSON.stringify(err)}`)
Expand Down
9 changes: 4 additions & 5 deletions packages/ssi-express-support/src/openid-connect-rp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,10 @@ export function getLogoutCallbackEndpoint(router: Router, opts?: ISingleEndpoint
router.get(path, (req, res, next) => {
try {
req.logout((err) => {
if (err) {
console.log(`Error during calling logout-callback: ${JSON.stringify(err)}`)
}
}
)
if (err) {
console.log(`Error during calling logout-callback: ${JSON.stringify(err)}`)
}
})
return res.redirect(env('OIDC_FRONTEND_LOGOUT_REDIRECT_URL', PREFIX) ?? '/')
} catch (e) {
return sendErrorResponse(res, 500, 'An unexpected error occurred during logout callback', e)
Expand Down
101 changes: 51 additions & 50 deletions packages/web3-provider-headless/__tests__/agent.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,69 @@
import {ExpressBuilder, ExpressCorsConfigurer} from "@sphereon/ssi-express-support";
import {SphereonKeyManager} from "@sphereon/ssi-sdk-ext.key-manager";
import {SphereonKeyManagementSystem} from "@sphereon/ssi-sdk-ext.kms-local";
import {createAgent, IDIDManager, IKeyManager, IResolver, TAgent} from "@veramo/core";
import {DIDManager, MemoryDIDStore} from "@veramo/did-manager";
import {getDidKeyResolver, KeyDIDProvider} from "@veramo/did-provider-key";
import {DIDResolverPlugin} from "@veramo/did-resolver";
import {MemoryKeyStore, MemoryPrivateKeyStore} from "@veramo/key-manager";
import {Resolver} from "did-resolver";
import {Signer} from 'ethers'
import {IRequiredContext, IWeb3Provider} from '../src'
import {EthersHeadlessProvider} from "../src";
import {EthersKMSSignerBuilder} from "../src";
import {createRpcServer} from "../src";
import {injectWeb3Provider} from './web3-helper'

import { ExpressBuilder, ExpressCorsConfigurer } from '@sphereon/ssi-express-support'
import { SphereonKeyManager } from '@sphereon/ssi-sdk-ext.key-manager'
import { SphereonKeyManagementSystem } from '@sphereon/ssi-sdk-ext.kms-local'
import { createAgent, IDIDManager, IKeyManager, IResolver, TAgent } from '@veramo/core'
import { DIDManager, MemoryDIDStore } from '@veramo/did-manager'
import { getDidKeyResolver, KeyDIDProvider } from '@veramo/did-provider-key'
import { DIDResolverPlugin } from '@veramo/did-resolver'
import { MemoryKeyStore, MemoryPrivateKeyStore } from '@veramo/key-manager'
import { Resolver } from 'did-resolver'
import { Signer } from 'ethers'
import { IRequiredContext, IWeb3Provider } from '../src'
import { EthersHeadlessProvider } from '../src'
import { EthersKMSSignerBuilder } from '../src'
import { createRpcServer } from '../src'
import { injectWeb3Provider } from './web3-helper'

const agent: TAgent<IKeyManager & IDIDManager & IResolver> = createAgent({
plugins: [
new SphereonKeyManager({
store: new MemoryKeyStore(),
kms: {
local: new SphereonKeyManagementSystem(new MemoryPrivateKeyStore()),
},
}),
new DIDManager({
providers: {
'did:key': new KeyDIDProvider({defaultKms: 'local'}),
},
store: new MemoryDIDStore(),
defaultProvider: 'did:key',
}),
new DIDResolverPlugin({
resolver: new Resolver({
...getDidKeyResolver()
}),
}),
],
plugins: [
new SphereonKeyManager({
store: new MemoryKeyStore(),
kms: {
local: new SphereonKeyManagementSystem(new MemoryPrivateKeyStore()),
},
}),
new DIDManager({
providers: {
'did:key': new KeyDIDProvider({ defaultKms: 'local' }),
},
store: new MemoryDIDStore(),
defaultProvider: 'did:key',
}),
new DIDResolverPlugin({
resolver: new Resolver({
...getDidKeyResolver(),
}),
}),
],
})
const context: IRequiredContext = {agent}
agent.keyManagerImport({
const context: IRequiredContext = { agent }
agent
.keyManagerImport({
// privateKeyHex: '8f2695a99c416ab9241fc75ae53f90b083aecff9e4463e046a1527f456b502c6',
privateKeyHex: process.env.WEB3_IMPORT_PRIVATEKEY_HEX ?? 'f5c0438db93a60a191530c0dd61a118bfb26ce4afb1ee54ea67deb15ec92d164',
kms: 'local',
type: 'Secp256k1'
}).then(key => {
console.log("=============KEY===========")
type: 'Secp256k1',
})
.then((key) => {
console.log('=============KEY===========')
console.log(JSON.stringify(key))
console.log("=============KEY===========")
console.log('=============KEY===========')
const kmsSigner = new EthersKMSSignerBuilder().withContext(context).withKeyRef(key).build()
let signers: Signer[]
let web3Provider: IWeb3Provider

// Inject window.ethereum instance
[signers, web3Provider] = injectWeb3Provider({signers: [kmsSigner]})
;[signers, web3Provider] = injectWeb3Provider({ signers: [kmsSigner] })
const headlessProvider = web3Provider as EthersHeadlessProvider
console.log(`Signers: ${signers}`)
const expressSupport = ExpressBuilder.fromServerOpts({
hostname: "0.0.0.0",
port: 3000,
basePath: "/web3/rpc"
}).withCorsConfigurer(new ExpressCorsConfigurer().allowOrigin("*")).build()
hostname: '0.0.0.0',
port: 3000,
basePath: '/web3/rpc',
})
.withCorsConfigurer(new ExpressCorsConfigurer().allowOrigin('*'))
.build()
createRpcServer(headlessProvider, expressSupport)
expressSupport.start()
})
})
console.log('DONE')


6 changes: 3 additions & 3 deletions packages/web3-provider-headless/__tests__/web3-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { createWeb3Provider, IWeb3Provider } from '../src'
*
* @returns {Array} An array containing the wallets and the web3Provider instance
*/
export function injectWeb3Provider(opts?: {signers?: Signer[]}): [Signer[], IWeb3Provider] {
/* const wallet: Signer = Wallet.fromEncryptedJsonSync(
export function injectWeb3Provider(opts?: { signers?: Signer[] }): [Signer[], IWeb3Provider] {
/* const wallet: Signer = Wallet.fromEncryptedJsonSync(
'{"address":"0c45d104d250b72301a7158fb27a8a4d4567b9ce","crypto":{"cipher":"aes-128-ctr","ciphertext":"6d388a272b062d155b18100ca7c78ad2fcd49c21171677ec37a5c913e768bc9e","cipherparams":{"iv":"f73a50cf77dcafdd498a225b8f0da125"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"088ade08639879b3532b49266ba16078cfe44515707ba3b17c9a911d750b6e40"},"mac":"905c5baef19f3c545dd7708be4ee94a95231a1e1c24966e97ccb4f01e9721b9a"},"id":"85a4618e-1f41-4cfe-bc62-0120aa7d517c","version":3}',
'rvvb'
)*/
Expand All @@ -24,7 +24,7 @@ export function injectWeb3Provider(opts?: {signers?: Signer[]}): [Signer[], IWeb
wallets,
[100], // Chain ID - 31337 or is a common testnet id
// [1337], 'http://127.0.0.1:8545' // Ethereum client's JSON-RPC URL
'https://rpc.genx.minimal-gaia-x.eu'
'https://rpc.genx.minimal-gaia-x.eu'
)

// Expose the web3Provider instance to the global window object
Expand Down
26 changes: 6 additions & 20 deletions packages/web3-provider-headless/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,15 @@ export class ErrorWithCode extends Error {
}
}

export const Deny = (): ErrorWithCode =>
new ErrorWithCode('The user rejected the request.', 4001)
export const Deny = (): ErrorWithCode => new ErrorWithCode('The user rejected the request.', 4001)

export const Unauthorized = (): ErrorWithCode =>
new ErrorWithCode(
'The requested method and/or account has not been authorized by the user.',
4100
)
export const Unauthorized = (): ErrorWithCode => new ErrorWithCode('The requested method and/or account has not been authorized by the user.', 4100)

export const UnsupportedMethod = (): ErrorWithCode =>
new ErrorWithCode('The Provider does not support the requested method.', 4200)
export const UnsupportedMethod = (): ErrorWithCode => new ErrorWithCode('The Provider does not support the requested method.', 4200)

export const Disconnected = (): ErrorWithCode =>
new ErrorWithCode('The Provider is disconnected from all chains.', 4900)
export const Disconnected = (): ErrorWithCode => new ErrorWithCode('The Provider is disconnected from all chains.', 4900)

export const ChainDisconnected = (): ErrorWithCode =>
new ErrorWithCode(
'The Provider is not connected to the requested chain.',
4901
)
export const ChainDisconnected = (): ErrorWithCode => new ErrorWithCode('The Provider is not connected to the requested chain.', 4901)

export const UnrecognizedChainID = (): ErrorWithCode =>
new ErrorWithCode(
'Unrecognized chain ID. Try adding the chain using `wallet_addEthereumChain` first.',
4902
)
new ErrorWithCode('Unrecognized chain ID. Try adding the chain using `wallet_addEthereumChain` first.', 4902)
Loading

0 comments on commit 00fc40a

Please sign in to comment.