diff --git a/ARCs/arc-0031.md b/ARCs/arc-0031.md
new file mode 100644
index 000000000..ff31ddb69
--- /dev/null
+++ b/ARCs/arc-0031.md
@@ -0,0 +1,269 @@
+---
+arc: 31
+title: Authentication with Algorand accounts
+description: Use Algorand accounts to authenticate with third-party services
+author: Stefano De Angelis (@deanstef)
+discussions-to: https://github.com/algorandfoundation/ARCs/issues/42
+status: Draft
+type: Meta
+created: 2022-04-05
+---
+
+# Authentication with Algorand accounts
+
+A standard for authentication with Algorand accounts.
+
+## Abstract
+
+This ARC introduces a standard for authenticating users with their Algorand accounts. It leverages asymmetric encryption <*PK, SK*> to verify the identity of a user, owner of an Algorand account. This approach fosters the adoption of novel identity management systems for both Web3 and Web2 applications.
+
+### Definitions
+
+- **System**: any frontend/backend application, service provider, or in general an entity not based on blockchain;
+- **Credentials**: any type of authentication used by users to access their online accounts, e.g. username/password, PIN, public/secret key pair;
+- **Blockchain identity**: a public/secret key pair <*PK, SK*> representing a blockchain account;
+- **Algorand account**: a blockchain identity on Algorand identified with the key pair <*PKa, SKa*>;
+- **Algorand address**: the public key *PKa* of an Algorand account;
+- **User**: an Algorand account holder;
+- **Verifier**: a system that needs to verify the identity of a User;
+- **dApp**: a decentralized Algorand application that natively runs on the Algorand blockchain, aka "*smart contract*";
+- **Wallet**: an off-chain application that stores the secret keys *SKa*s of Algorand accounts and can display and sign transactions for these accounts;
+- **message**: a generic string of bytes;
+- **digital signature**: a message signed with the private key of a blockchain identity.
+
+## Motivation
+
+In Web3 users interacting with dApps must be authenticated with a blockchain identity (account for Algorand). Having dApps and traditional Web2 systems increasingly more interconnected, it is not difficult to imagine users consuming services both from a dApp and a Web2 application simultaneously. In this case, a single source of authentication should be used to avoid separation between credentials used for dApps and traditional Web2 services.
+
+This ARC provides a standard for users' authentication in Web2 services leveraging Algorand accounts.
+
+## Specification
+
+The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in RFC-2119
+> Comments like this are non-normative.
+
+Interfaces are defined in TypeScript. All the objects that are defined are valid JSON objects, and all JSON string types are UTF-8 encoded.
+
+This ARC uses interchangeably the terms "*blockchain address*", "*public key*", and "*PK*" to indicate the on-chain address of a blockchain identity, and in particular of an Algorand account.
+
+### Overview
+
+This document describes a standard approach to authenticate a User with a blockchain identity. Algorand addresses are used as a *unique identifiers*, and the secret keys to digitally sign *messages* as a proof of identity.
+
+To sum up, given an Algorand account <*PKa, SKa*>, this ARC defines a standards for:
+
+- creating an [ARC-31](./arc-0031.md) compliant digital signature with *SKa*;
+- verifying an [ARC-31](./arc-0031.md) compliant digital signature with *PKa*.
+
+### Assumptions
+
+The standard proposed in this document works under the following assumptions:
+
+- User and Verifier communicate over secure SSL/TLS encrypted channels;
+- The Verifier knows the Users’ *PKa*;
+- For each *PKa* the Verifier generates a unique message to be signed;
+- The message MUST change arbitrarily for each authentication request to avoid [replay attacks](https://en.wikipedia.org/wiki/Replay_attack);
+- User's secret key is safely kept into a Wallet;
+- Users do not change their public address *PKa* for authentication;
+- Users **MUST** use Algorand compliant keys to sign the messages;
+- LogicSigs and Application addresses are not supported;
+
+### Authentication Mechanism
+
+The authentication mechanism defined in this ARC works as follows: a Users sends an authentication request to the Verifier specifying the Algorand account <*PKa, SKa*>.
+
+> Note that Algorand transforms traditional 32-bytes cryptographic keys into more readable and user-friendly objects. A detailed description of such a transformation can be found on the developer portal.
+
+The Verifier responds with a message to be signed with the account's secret key *SKa*. The User queries the Wallet to sign the message. At that stage, the Wallet **MUST** check the message origin with the expected Verifier (to protect Users from [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)). Once the message is signed, the User sends the result back to the Verifier. Finally, the Verifier checks the signature and, if it is all good, authenticates the User.
+
+```mermaid
+sequenceDiagram
+ actor A as Alice
+ participant W as Wallet
+ actor B as Bob
+ A-->>W: Connect to Bob with PKa
+ activate W
+ W->>B: GET message for PKa
+ activate B
+ B->>B: Create a new msg for PKa
+ B->>W: msg
+ deactivate B
+ W->>W: Check
+ W-->>A: Show msg origin
+ Note right of A: Confirm signature
+ A-->>W:
+ W->>B:
+ deactivate W
+ activate B
+ B->>B: Verify Sig(msg) with PKa and msg
+ Note right of B: if Sig(msg) is valid then authenticate user
+ B-->>A: Authentication OK/KO
+ deactivate B
+```
+
+The diagram above summarizes the proposed mechanism. We consider the User, **Alice**, owner of an Algorand account <*PKa, SKa*> of which the secret key *SKa* is stored into a **Wallet**.
+
+> A wallet is any type of Algorand wallet, such as hot wallets like AlgoSigner, MyAlgo Wallet for browser and mobile wallets used through WalletConnect, and cold wallets like the Ledger Nano.
+
+Alice authenticates herself to the Verifier **Bob** sending back the digital signature `Sig(msg)` of message `msg` provided by Bob. The mechanism proceeds as follows:
+
+1. Alice initiates an authentication with *PKa* to Bob;
+2. Bob generates a message `msg` to be signed by Alice's *SKa*;
+3. Alice signs `msg` using her wallet; the Wallet inspects and displays the `msg` origin to be sure it came from Bob;
+4. Alice sends back the tuple `` to Bob;
+5. Bob verifies `Sig(msg)` with Alice's *PKa* and `msg`;
+6. If the signature is valid, Bob authenticates Alice.
+
+The ARC-31 defines a standardized message for authentication, called *Authentication Message*.
+
+### Authentication Message
+
+An *Authentication Message* `auth-msg` is a sequence of bytes representing a message to be signed. The Verifier requests Users to sign an `auth-msg` with their secret keys. Such a message **MUST** include the following information:
+
+- `domain name`: name of the Verifier domain;
+- `Algorand address`: User's *PKa* to be authenticated;
+- `nonce`: a unique/random value generated by the Verifier;
+- `description`: Verifier details or general description;
+- `metadata`: arbitrary message data.
+
+The *Authentication Message* is represented with the following interface:
+
+```typescript
+interface AuthMessage {
+ /** The domain name of the Verifier */
+ domain: string;
+ /** Algorand account to authenticate with*/
+ authAcc: string;
+ /** Unique random nonce generated by the Verifier */
+ nonce: string;
+ /** Optional, description of the Verifier */
+ desc?: string;
+ /** Optional, metadata */
+ meta?: string;
+}
+```
+
+The `auth-msg` **SHOULD** be compliant with [ARC-2](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md), having the parameter `\`=`arc31`, for example:
+
+```json
+arc31:j{
+ "domain": "www.verifierdomain.com",
+ "authAcc": "KTGP47G64KCXWJS64W7SGJNKTHE37TYDCI64USXI3XOYE6ZSH4LCI7NIDA",
+ "nonce": "1234abcde!%",
+ "desc": "The Verifier",
+ "meta": "arbitrary attached data",
+}
+```
+
+The `nonce` field **MUST** be unique for each authentication and **MUST NOT** be used more than once to avoid replay attacks.
+
+#### Signing the Authentication Message
+
+The `auth-msg` **MUST** be exchanged as a base64 encoded [msgpacked](https://msgpack.org/index.html) message, prefixed with the `"AX"` domain separator, such that:
+
+`msg =("AX" + msgpack_encode(auth-msg))`.
+
+### Authenticate Rekeyed Accounts
+
+Algorand accounts can be rekeyed. Rekeying means that the signing key of a static public address *PKa* is dynamically rotated to another secret key. In this case, the original address controlled by *SKa'* is called *authorization address* of *PKa*, and it **MUST** be used to check the signature of *PKa*. In this ARC we indicate the *authorization address* with the account **.
+
+> To learn more about Algorand Rekeying feature visit the [Rekey section](https://developer.algorand.org/docs/get-details/accounts/rekey/?from_query=rekey#create-publication-overlay) of the developer portal.
+
+The *authorization address* of an account can be checked directly from the Algorand blockchain. Indeed, a Verifier can inspect the [account API](https://developer.algorand.org/docs/rest-apis/algod/v2/#get-v2accountsaddress) to check the account's `auth-addr` parameter. This parameter, if not empty, indicates the *authorization address* *PKa'*.
+
+The ARC-31 allows rekeyed accounts to be used for authentication. In this case, the Verifier must check the signature of a *PKa* with the *authorization address* *PKa'*. This address must be provided by the User along with the original address *PKa* and the digital signature. The Verifier, on his side, can check the validity of *PKa'* by looking at the Algorand blockchain. The diagram below details the protocol handling rekeyed accounts.
+
+```mermaid
+sequenceDiagram
+ actor A as Alice
+ participant W as Wallet
+ actor B as Bob
+ participant Algorand
+ A-->>W: Connect to Bob with PKa
+ activate W
+ W->>B: GET message for PKa
+ activate B
+ B->>B: Create a new msg for PKa
+ B->>W: msg
+ deactivate B
+ W->>W: Check
+ W-->>A: Show msg origin
+ Note right of A: Confirm signature with auth-addr
+ A-->>W:
+ W->>B:
+ deactivate W
+ activate B
+ B->>Algorand: Retrieve PKa auth-addr
+ activate Algorand
+ Algorand-->>B: PKa'
+ deactivate Algorand
+ B->>B: Verify PKa auth-addr
+ B->>B: Verify Sig(msg) with PKa' and msg
+ Note right of B: if Sig(msg) is valid then authenticate user
+ B-->>A: Authentication OK/KO
+ deactivate B
+```
+
+### Authenticate Multisignature Accounts
+
+Algorand accounts can be Multisignature (or MultiSig). A MultiSig account is a logical representation of an ordered set of addresses with a threshold and version.
+
+> To learn more about Algorand MultiSig feature visit the [Multisignature section](https://developer.algorand.org/docs/get-details/accounts/create/#multisignature) of the developer portal.
+
+The ARC-31 allows MultiSig accounts to be used for authentication. Assuming a MultiSig address *PKa_msig* composed by three Algorand accounts identified with the addresses *PKa', PKa'', PKa'''*, `threshold=2`, and `version=1`, the authentication should work as follows:
+
+1. An authentication request with *PKa_msig* is sent from the User to the Verifier;
+2. The Verifier responds with a new authentication message `msg`;
+3. The User collects the threshold signatures of `msg` and responds with **, where *PKa*s are the ordered set of addresses of *PKa_msig*, *Sig*s are the collected signatures, `2` is the threshold and `1` is the MultiSig version;
+4. The Verifier firstly checks the *PKa_msig* against the list of addresses, the threshold and the version received, then verifies the signatures; if a threshold of valid signatures is received, the User can be authenticated.
+
+The diagram below details the protocol handling MultiSig accounts.
+
+```mermaid
+sequenceDiagram
+ actor A as Alice
+ participant W as Wallet
+ actor B as Bob
+ A-->>W: Connect to Bob with PKa_msig
+ activate W
+ W->>B: GET message for PKa_msig
+ activate B
+ B->>B: Create a new msg for PKa_msig
+ B->>W: msg
+ deactivate B
+ W->>W: Check
+ W-->>A: Show msg origin
+ Note right of A: Collect signatures with PKa' and PKa''
+ A-->>W:
+ W->>B:
+ deactivate W
+ activate B
+ B->>B: Verify PKa_msig with (PKa', PKa'', PKa''', 2, 1)
+ B->>B: Verify Sig'(msg) with PKa' and msg
+ B->>B: Verify Sig''(msg) with PKa'' and msg
+ Note right of B: if threshold of valid signatures then authenticate user
+ B-->>A: Authentication OK/KO
+ deactivate B
+```
+
+### How to verify a digital signature?
+
+A digital signature generated with the secret key *SKa* of an Algorand account can be verified with its respective 32-byte public key *PKa*. The Verifier needs to decode the public key *PK* from the Algorand address, and it must know the original `auth-msg`. For example, assuming the digital signature `Sig(msg)` the Verifier can validate it using the Algorand SDK as follows:
+
+1. decode the Algorand address into a traditional 32-bytes public key *PK*;
+2. Compute `msg =("AX" + msgpack_encode(auth-msg))`;
+3. use an open-source cryptographic library (e.g. Python lib PyNaCl) to verify the signature `Sig(msg)` with *PK*.
+
+## Security Considerations
+
+An attacker **MAY** attempt to cheat with the system by impersonating another User or Verifier. This is possible if the attacker can intercept the digital signature and use the same signature in a replay-attack or man-in-the-middle attack. To mitigate this scenario, the Verifier **MUST** generate a new message for each authentication request, and Wallets must always check the `auth-msg` domain field.
+
+## Reference Implementation
+
+The ARC-31 reference implementation is available in the `assets` directory of this repo `assets/arc-0031`. It provides an example of client-server authentication with ARC-31. The reference implementation uses [MyAlgoWallet](https://wallet.myalgo.com/) as the unique wallet (at the time of writing) providing the possibility of signing random bytes.
+
+Reference implementation credits: [mrcointreau](https://github.com/mrcointreau)
+
+## Copyright
+
+Copyright and related rights waived via CCO.
diff --git a/assets/arc-0031/.env.example b/assets/arc-0031/.env.example
new file mode 100644
index 000000000..d6902936e
--- /dev/null
+++ b/assets/arc-0031/.env.example
@@ -0,0 +1,4 @@
+ALGORAND_CHAIN_ID=TestNet
+API_URL=http://arc-0031-server:3001/api/v1/
+SERVICE_NAME=www.servicedomain.com
+SERVICE_DESCRIPTION=Service Description
diff --git a/assets/arc-0031/.gitignore b/assets/arc-0031/.gitignore
new file mode 100644
index 000000000..98a4f7a0c
--- /dev/null
+++ b/assets/arc-0031/.gitignore
@@ -0,0 +1,29 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+.env
+.env.*.
+!.env.example
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+!.vscode/settings.json.example
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/assets/arc-0031/README.md b/assets/arc-0031/README.md
new file mode 100644
index 000000000..51f40ae45
--- /dev/null
+++ b/assets/arc-0031/README.md
@@ -0,0 +1,38 @@
+# ARC-0031 Reference Implementation
+
+**⚠️ Disclamer: This repo provides a simple example of ARC-31. The code is not audited and therefore, it should not be used for production environments.**
+
+The ARC-31 reference implementation is a self contained, standalone repo providing both client and server interfaces. It simulates a User, previously registered to the Validator, authenticating with his Algorand public key *PKa* to a service exposed by the Verifier.
+
+The example shows the entire workflow of authentication using a standalone Algorand account signing an Authentication message. Rekey and MultiSig use cases are not covered yet.
+
+## User registration
+
+Add registered users to the `server/mock/users.db.json` array. The `nonce` field must be left empty `''`.
+
+## Run via Docker Compose
+
+From the root folder run
+
+```
+cp .env.example .env
+docker compose up --build
+```
+
+Visit `localhost`
+
+## Run local development environment
+
+### Requirements
+- `node.js`
+- `npm`
+
+From both `client`and `server` folders run
+
+```
+cp .env.example .env
+npm ci
+npm run dev
+```
+
+Visit `localhost:3001`
diff --git a/assets/arc-0031/client/.env.example b/assets/arc-0031/client/.env.example
new file mode 100644
index 000000000..5dfd775dd
--- /dev/null
+++ b/assets/arc-0031/client/.env.example
@@ -0,0 +1,2 @@
+NUXT_API_URL=http://localhost:3000/api/v1/
+NUXT_PUBLIC_ALGORAND_CHAIN_ID=TestNet
diff --git a/assets/arc-0031/client/.eslintrc b/assets/arc-0031/client/.eslintrc
new file mode 100644
index 000000000..d4e1a03d3
--- /dev/null
+++ b/assets/arc-0031/client/.eslintrc
@@ -0,0 +1,45 @@
+{
+ "extends": [
+ "@nuxtjs/eslint-config-typescript"
+ ],
+ "parserOptions": {
+ "project": [
+ "**/tsconfig.json"
+ ],
+ "extraFileExtensions": [
+ ".vue"
+ ]
+ },
+ "rules": {
+ "@typescript-eslint/consistent-type-exports": "error",
+ "@typescript-eslint/consistent-type-imports": "error",
+ "@typescript-eslint/indent": ["error", 2]
+ },
+ "overrides": [
+ {
+ "files": [
+ "**/*.{js,ts,vue}"
+ ],
+ "rules": {
+ "import/order": [
+ "error",
+ {
+ "newlines-between": "always",
+ "alphabetize": {
+ "order": "asc",
+ "orderImportKind": "asc"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "files": [
+ "**/*.vue"
+ ],
+ "rules": {
+ "vue/multi-word-component-names": "warn"
+ }
+ }
+ ]
+}
diff --git a/assets/arc-0031/client/.gitignore b/assets/arc-0031/client/.gitignore
new file mode 100644
index 000000000..b2bad60be
--- /dev/null
+++ b/assets/arc-0031/client/.gitignore
@@ -0,0 +1,33 @@
+# Nuxt dev/build outputs
+.output
+.data
+.nuxt
+.nitro
+.cache
+dist
+
+# yarn 2
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/sdks
+!.yarn/versions
+
+# Node dependencies
+node_modules
+
+# Logs
+logs
+*.log
+
+# Misc
+.DS_Store
+.fleet
+.idea
+
+# Local env files
+.env
+.env.*
+!.env.example
diff --git a/assets/arc-0031/client/Dockerfile b/assets/arc-0031/client/Dockerfile
new file mode 100644
index 000000000..82122e9f1
--- /dev/null
+++ b/assets/arc-0031/client/Dockerfile
@@ -0,0 +1,13 @@
+FROM node:20-slim AS base
+WORKDIR /client
+
+FROM base AS build
+COPY package*.json ./
+RUN npm ci && npm cache clean --force
+COPY . .
+RUN npm run build
+
+FROM base AS production
+COPY --from=build /client/.output /client/.output
+EXPOSE 3000
+ENTRYPOINT ["node", ".output/server/index.mjs"]
diff --git a/assets/arc-0031/client/README.md b/assets/arc-0031/client/README.md
new file mode 100644
index 000000000..d69a1159e
--- /dev/null
+++ b/assets/arc-0031/client/README.md
@@ -0,0 +1,42 @@
+# Nuxt 3 Minimal Starter
+
+Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
+
+## Setup
+
+Make sure to install the dependencies:
+
+```bash
+# yarn
+yarn install
+
+# npm
+npm install
+
+# pnpm
+pnpm install --shamefully-hoist
+```
+
+## Development Server
+
+Start the development server on http://localhost:3000
+
+```bash
+npm run dev
+```
+
+## Production
+
+Build the application for production:
+
+```bash
+npm run build
+```
+
+Locally preview production build:
+
+```bash
+npm run preview
+```
+
+Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
diff --git a/assets/arc-0031/client/app.config.ts b/assets/arc-0031/client/app.config.ts
new file mode 100644
index 000000000..7d278d272
--- /dev/null
+++ b/assets/arc-0031/client/app.config.ts
@@ -0,0 +1,7 @@
+export default defineAppConfig({
+ ui: {
+ notifications: {
+ position: 'top-0 bottom-auto'
+ }
+ }
+})
diff --git a/assets/arc-0031/client/app.vue b/assets/arc-0031/client/app.vue
new file mode 100644
index 000000000..a793eda96
--- /dev/null
+++ b/assets/arc-0031/client/app.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/arc-0031/client/layouts/default.vue b/assets/arc-0031/client/layouts/default.vue
new file mode 100644
index 000000000..ec68d77c5
--- /dev/null
+++ b/assets/arc-0031/client/layouts/default.vue
@@ -0,0 +1,6 @@
+
+