feat(SIWE): Add siwe support to the webSdk integration

This PR implements the functions needed for siwe in the webSdk integration, updates the WC version and fixes an issue where the webpack does not automatically inject `Buffer` plugin needed by the SIWE impl in WC.
This commit is contained in:
Alex Jbanca 2024-10-17 18:02:51 +03:00 committed by Alex Jbanca
parent d4e1539901
commit 7553ae45e0
8 changed files with 1627 additions and 1773 deletions

View File

@ -69,6 +69,26 @@ WalletConnectSDKBase {
wcCalls.rejectSessionRequest(topic, id, error)
}
populateAuthPayload: function(id, authPayload, chains, methods) {
wcCalls.populateAuthPayload(id, authPayload, chains, methods)
}
formatAuthMessage: function(id, request, iss) {
wcCalls.formatAuthMessage(id, request, iss)
}
acceptSessionAuthenticate: function(id, auths) {
wcCalls.acceptSessionAuthenticate(id, auths)
}
rejectSessionAuthenticate: function(id, error) {
wcCalls.rejectSessionAuthenticate(id, error)
}
buildAuthObject: function(id, authPayload, signature, iss) {
wcCalls.buildAuthObject(id, authPayload, signature, iss)
}
QtObject {
id: d
@ -253,6 +273,81 @@ WalletConnectSDKBase {
`
)
}
function populateAuthPayload(id, authPayload, chains, methods) {
console.debug(`WC WalletConnectSDK.wcCall.populateAuthPayload; id: "${id}", authPayload: ${JSON.stringify(authPayload)}, chains: ${JSON.stringify(chains)}, methods: ${JSON.stringify(methods)}`)
d.engine.runJavaScript(`
wc.populateAuthPayload(${JSON.stringify(authPayload)}, ${JSON.stringify(chains)}, ${JSON.stringify(methods)})
.then((value) => {
wc.statusObject.onPopulateAuthPayloadResponse("${id}", value, "")
})
.catch((e) => {
wc.statusObject.onPopulateAuthPayloadResponse("${id}", "", e.message)
})
`
)
}
function formatAuthMessage(id, request, iss) {
console.debug(`WC WalletConnectSDK.wcCall.formatAuthMessage; id: ${id}, request: ${JSON.stringify(request)}, iss: ${iss}`)
d.engine.runJavaScript(`
wc.formatAuthMessage(${JSON.stringify(request)}, "${iss}")
.then((value) => {
wc.statusObject.onFormatAuthMessageResponse(${id}, value, "")
})
.catch((e) => {
wc.statusObject.onFormatAuthMessageResponse(${id}, "", e.message)
})
`
)
}
function buildAuthObject(id, authPayload, signature, iss) {
console.debug(`WC WalletConnectSDK.wcCall.buildAuthObject; id: ${id}, authPayload: ${JSON.stringify(authPayload)}, signature: ${signature}, iss: ${iss}`)
d.engine.runJavaScript(`
wc.buildAuthObject(${JSON.stringify(authPayload)}, "${signature}", "${iss}")
.then((value) => {
wc.statusObject.onBuildAuthObjectResponse(${id}, value, "")
})
.catch((e) => {
wc.statusObject.onBuildAuthObjectResponse(${id}, "", e.message)
})
`
)
}
function acceptSessionAuthenticate(id, auths) {
console.debug(`WC WalletConnectSDK.wcCall.acceptSessionAuthenticate; id: ${id}, auths: ${JSON.stringify(auths)}`)
d.engine.runJavaScript(`
wc.acceptSessionAuthenticate(${id}, ${JSON.stringify(auths)})
.then((value) => {
wc.statusObject.onAcceptSessionAuthenticateResult(${id}, value, "")
})
.catch((e) => {
wc.statusObject.onAcceptSessionAuthenticateResult(${id}, "", e.message)
})
`
)
}
function rejectSessionAuthenticate(id, error) {
console.debug(`WC WalletConnectSDK.wcCall.rejectSessionAuthenticate; id: ${id}, error: "${error}"`)
d.engine.runJavaScript(`
wc.rejectSessionAuthenticate(${id}, ${error})
.then((value) => {
wc.statusObject.onRejectSessionAuthenticateResult(${id}, value, "")
})
.catch((e) => {
wc.statusObject.onRejectSessionAuthenticateResult(${id}, "", e.message)
})
`
)
}
}
QtObject {
@ -371,6 +466,36 @@ WalletConnectSDKBase {
console.debug(`WC WalletConnectSDK.onSessionRequestExpire; id: ${id}`)
root.sessionRequestExpired(id)
}
function onPopulateAuthPayloadResponse(id, payload, error) {
console.debug(`WC WalletConnectSDK.onPopulateAuthPayloadResponse; id: ${id}, payload: ${JSON.stringify(payload)}, error: ${error}`)
root.populateAuthPayloadResult(id, payload, error)
}
function onFormatAuthMessageResponse(id, message, error) {
console.debug(`WC WalletConnectSDK.onFormatAuthMessageResponse; id: ${id}, message: ${JSON.stringify(message)}, error: ${error}`)
root.formatAuthMessageResult(id, message, error)
}
function onBuildAuthObjectResponse(id, authObject, error) {
console.debug(`WC WalletConnectSDK.onBuildAuthObjectResponse; id: ${id}, authObject: ${JSON.stringify(authObject)}, error: ${error}`)
root.buildAuthObjectResult(id, authObject, error)
}
function onSessionAuthenticate(details) {
console.debug(`WC WalletConnectSDK.onSessionAuthenticate; details: ${JSON.stringify(details)}`)
root.sessionAuthenticateRequest(details)
}
function onAcceptSessionAuthenticateResult(id, result, error) {
console.debug(`WC WalletConnectSDK.onAcceptSessionAuthenticateResult; id: ${id}, result: ${JSON.stringify(result)}, error: ${error}`)
root.acceptSessionAuthenticateResult(id, result, error)
}
function onRejectSessionAuthenticateResult(id, result, error) {
//console.debug(`WC WalletConnectSDK.onRejectSessionAuthenticateResult; id: ${id}, result: ${result}, error: ${error}`)
root.rejectSessionAuthenticateResult(id, result, error)
}
}
WebEngineLoader {

View File

@ -15,10 +15,12 @@ Item {
signal sessionRequestExpired(var id)
signal sessionRequestEvent(var sessionRequest)
signal sessionRequestUserAnswerResult(string topic, string id, bool accept /* not reject */, string error)
signal authRequest(var request)
signal authMessageFormated(string formatedMessage, string address)
signal authRequestUserAnswerResult(bool accept, string error)
signal sessionAuthenticateRequest(var sessionData)
signal populateAuthPayloadResult(var id, var authPayload, string error)
signal formatAuthMessageResult(var id, var request, string error)
signal acceptSessionAuthenticateResult(var id, var result, string error)
signal rejectSessionAuthenticateResult(var id, var result, string error)
signal buildAuthObjectResult(var id, var authObject, string error)
signal sessionDelete(var topic, string error)
@ -60,4 +62,24 @@ Item {
property var rejectSessionRequest: function(topic, id, error) {
console.error("rejectSessionRequest not implemented")
}
property var populateAuthPayload: function (id, authPayload, chains, methods) {
console.error("populateAuthPayload not implemented")
}
property var formatAuthMessage: function(id, request, iss) {
console.error("formatAuthMessage not implemented")
}
property var buildAuthObject: function(id, authPayload, signature, iss) {
console.error("buildAuthObject not implemented")
}
property var acceptSessionAuthenticate: function(id, auths) {
console.error("acceptSessionAuthenticate not implemented")
}
property var rejectSessionAuthenticate: function(id, error) {
console.error("rejectSessionAuthenticate not implemented")
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,10 @@
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
@ -13,6 +20,8 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
/**
* [js-sha3]{@link https://github.com/emn178/js-sha3}
*

File diff suppressed because it is too large Load Diff

View File

@ -16,9 +16,9 @@
"start": "webpack serve --mode development --open"
},
"dependencies": {
"@reown/walletkit": "^1.1.0",
"@walletconnect/utils": "^2.17.0",
"@walletconnect/jsonrpc-utils": "^1.0.8",
"@walletconnect/core": "^2.17.0"
"@reown/walletkit": "^1.1.1",
"@walletconnect/core": "^2.17.1",
"@walletconnect/utils": "^2.17.1",
"buffer": "^6.0.3"
}
}

View File

@ -2,7 +2,7 @@ import { Core } from "@walletconnect/core";
import { WalletKit } from "@reown/walletkit";
// import the builder util
import { buildApprovedNamespaces, getSdkError } from "@walletconnect/utils";
import { buildApprovedNamespaces, getSdkError, populateAuthPayload, buildAuthObject } from "@walletconnect/utils";
import { formatJsonRpcResult, formatJsonRpcError } from "@walletconnect/jsonrpc-utils";
window.wc = {
@ -102,6 +102,16 @@ window.wc = {
window.wc.core.relayer.on("relayer_disconnect", () => {
wc.statusObject.echo("debug", `WC unhandled event: "relayer_disconnect" connection to the relay server is lost`);
})
window.wc.walletKit.on("session_authenticate", (payload) => {
// Process the authentication request here.
// Steps include:
// 1. Populate the authentication payload with the supported chains and methods
// 2. Format the authentication message using the payload and the user's account
// 3. Present the authentication message to the user
// 4. Sign the authentication message(s) to create a verifiable authentication object(s)
// 5. Approve the authentication request with the authentication object(s)
wc.statusObject.onSessionAuthenticate(payload)
})
resolve("");
} catch(error) {
@ -187,4 +197,44 @@ window.wc = {
}
);
},
populateAuthPayload: async function (authPayload, chains, methods) {
return populateAuthPayload({
authPayload,
chains,
methods,
});
},
formatAuthMessage: async function (request, iss) {
return wc.walletKit.formatAuthMessage({
request,
iss
});
},
buildAuthObject: async function (authPayload, signature, iss) {
return buildAuthObject(
authPayload,
{
t: 'eip191',
s: signature
},
iss
)
},
acceptSessionAuthenticate: async function(id, auths) { // Approve
return await window.wc.walletKit.approveSessionAuthenticate({
id,
auths
})
},
rejectSessionAuthenticate: async function(id, error) { // Reject
return await window.wc.walletKit.rejectSessionAuthenticate({
id: id,
reason: getSdkError('USER_REJECTED') // or choose a different reason if applicable
})
}
};

View File

@ -1,4 +1,5 @@
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
@ -19,4 +20,17 @@ module.exports = {
experiments: {
outputModule: true,
},
plugins: [
// Work around for Buffer is undefined:
// https://github.com/webpack/changelog-v5/issues/10
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
})
],
resolve: {
extensions: [ '.ts', '.js' ],
fallback: {
buffer: require.resolve("buffer"),
},
},
};