Sign-In with Conflux
Sign-In with Conflux (SIWC) is a new standard that allows people to use their web3 wallet identity when logging in to web services, as opposed to a username/password pair. It describes how Conflux accounts authenticate with off-chain services by signing a standard message format parameterized by scope, session details, and other security mechanisms (e.g., a nonce).
The goals of this specification are to provide a self-custodial alternative to centralized identity providers, improve interoperability across off-chain services for Conflux-based authentication, and provide wallet vendors a consistent machine-readable message format to achieve improved user experience and consent management.
SIWC is based on and inspired by Sign-In with Ethereum. You can add SIWC to your project easily using the npm package manager.
Getting Started
To add SIWC to your project, execute the following commands:
npm install siwc
npm install siwc-parser
Or with yarn
yarn add siwc
yarn add siwc-parser
SIWC is compatible with Metamask and Fluent wallet. You can find examples in the SIWC quickstart project.
Sign-In with Conflux Quickstart
SIWC Quickstart is a simple Client/Server demo to help developers get started with SIWC through a fully functional and easy-to-understand example. Once SIWC login is added to your project, users will have to sign a message on their wallet to authenticate. A message signature will be returned.
This signature can be sent to the backend for verification. If the signature is correct, the API will return true.
Four examples are available in the quickstart project:
- 00_print: Print a simple message example on the console.
- 01_frontend: Example implementation of a signer and a verification in Javascript.
- 02_backend: Example implementation of a verification API in NodeJS.
- 03_complete_app: Example of a simple complete App with sign-in on the frontend and verification / getInformations APIs on the backend.
Implementation
The following example shows how you can use SIWC in your project.
Frontend with eSpace
Simple message-sign and verification steps on Conflux eSpace.
const message = await createSiwcMessage(
await signer.getAddress(),
'Sign in with Conflux to the app.'
);const signature = await signer.signMessage(message);fetch(`${BACKEND_ADDR}/verify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ message, signature, 'espace' }),
credentials: 'include',
});
Frontend with Core Space
Simple message sign and verification on Conflux Core.
const message = await createSiwcMessage(
{accountId},
'Sign in with Conflux to the app.',
{chainId}
);const signature = await window.conflux.request({
method: `personal_sign`,
params: [message, {accountId}],
});fetch(`${BACKEND_ADDR}/verify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ message, signature, 'core' }),
credentials: 'include',
});
Note: accountId
is the address, chainId
is 1
for testnet and 1029
for mainnet.
Backend
The example below authenticates the user by checking if the submitted signature is correct.
app.post('/verify', async function (req, res) {
try {
if (!req.body.message) {
res.status(422).json({
message: 'Expected prepareMessage object as body.',
});
return;
} let message = new SiwcMessage(req.body.message);
const { space, signature } = req.body;
const spaceEnum = (space === 'core')
? Space.CONFLUX_CORE
: Space.CONFLUX_E_SPACE; const fields = await message.validate(signature, spaceEnum); if (fields.nonce !== req.session.nonce) {
console.log(req.session);
res.status(422).json({
message: `Invalid nonce.`,
});
return;
} req.session.siwc = fields;
req.session.cookie.expires = new Date(fields.expirationTime);
req.session.save(() => res.status(200).end());
} catch (e) {
req.session.siwc = null;
req.session.nonce = null;
console.error(e); switch (e) {
case ErrorTypes.EXPIRED_MESSAGE: {
req.session.save(() =>
res.status(440).json({ message: e.message })
);
break;
}
case ErrorTypes.INVALID_SIGNATURE: {
req.session.save(() =>
res.status(422).json({ message: e.message })
);
break;
}
default: {
req.session.save(() =>
res.status(500).json({ message: e.message })
);
break;
}
}
}
});
The complete app example is available in the quickstart project.
References
SIWC :
https://github.com/MPoulhazan/siwc
SIWC Quickstart :
https://github.com/MPoulhazan/siwc-quickstart
SIWC on NPM:
https://www.npmjs.com/package/siwc
Sign in with Ethereum :
https://login.xyz