Sign In With Frequency Developer Documentation and Tools
Sign In With Frequency (SIWF) provides documentation and tools to use with SIWF-compatible services such as Frequency Access (an easy-to-use custodial social wallet for users on Frequency).
Overview
There are a few main steps to authenticating using SIWF-compatible systems.
For example, when using Frequency Access:
- Your application sends the user the Frequency Access Authentication URL
- Frequency Access verifies the user, and the user signs the requested payload(s)
- Frequency Access sends the signed user payloads back to your application
- If needed, your application sends the signed payloads to Frequency
- Your application logs in the user, and the user's session begins
Actors
- Your Application: Any website, mobile application, etc. for which your user needs authentication
- SIWF service (e.g. Frequency Access): Verifies the user and provides the user with access to the entire Frequency Ecosystem
- Frequency Blockchain: Manages user delegations and additional social operations
User Delegations and Credentials
SIWF allows you to request that a user give you various delegations such as private graph changes, and credentials such as verified email.
- See a full list of Available Credentials
- See a full list of Available Delegations
Staging & Production
Using Frequency Access
Frequency Access has two deployments: Staging-Testnet and Production-Mainnet.
Production-Mainnet
URL: www.frequencyaccess.com
- Uses Frequency Mainnet
- Supports both SMS and Email verification
- Bot protection via hCaptcha
- Authorization Timeout: 30 seconds
Staging-Testnet
URL: testnet.frequencyaccess.com
- Uses Frequency Testnet on Paseo
- Supports ONLY Email and will not send SMS verification codes
- No uptime guarantees
- Limited bot protection
- May rate limit usage
- Authorization Timeout: 30 seconds
Prerequisites
- Have registered your application as a Provider on Frequency
- Have access to a Frequency RPC Node
Terms
- Frequency Provider: The identity of the application registered on Frequency
- Staging-Testnet: The staging environment
- Production-Mainnet: The production environment
- MSA: The Frequency blockchain account for a user
- SR25519: Schnorr signatures using
ed25519
over ECDSA - Delegation: The user permission for an application to act on their behalf
- Credential: Verified data about the user provided with permission of the user
Quick Start with JavaScript
This quick start uses the @projectlibertylabs/siwf
NPM package to quickly generate the request and validate the response from Frequency Access.
Installation
Install the NPM package. This package is both CommonJS, ES Module, and TypeScript compatible. TypeScript will be shown for the examples.
npm i @projectlibertylabs/siwf
Prerequisites
- Generate a Login Request Payload and Signature
Step 1: Generate the Request URL
import * as siwf from "@projectlibertylabs/siwf";
async function startLogin() {
// Get the signed base64url encoded payload
const signedRequest: string = getStaticProviderSignedRequest();
// Any additional parameters that do not collide with reserved parameter names
// on the Authentication URL are passed through unchanged.
// Remember that ONLY the callback path from the Signed Payload is secured via signature.
const additionalCallbackUrlParams: string = getWebOrApplicationCallbackUrlParams();
// Options with endpoint selection
// Endpoint may be tagged or specified in full
const options = { endpoint: "production" };
// Staging-Testnet Options
// const options = { endpoint: 'staging' };
const authenticationUrl = siwf.generateAuthenticationUrl(signedRequest, additionalCallbackUrlParams, options);
}
Step 2 (Web): Forward the User to a Browser
For website interactions, just forward the user to the returned authenticationUrl
.
Step 2 (Android/iOS): Forward the User to an Embedded Browser
For mobile applications, it is recommended to use an embedded browser and set the callbackDomain
in the signedRequest
and the callbackPath
to your application's Universal Link. This ensures that the user remains within the application environment and does not have to leave the app.
For more details, refer to the official documentation:
Step 3: Callback Processing
import * as siwf from "@projectlibertylabs/siwf";
async function handleCallback(incomingUrl: string) {
// Extract the `authorizationCode` from the URL
const url = new URL(incomingUrl);
const authorizationCode = url.searchParams.get("authorizationCode");
// Same options as before
const options = { endpoint: "production" };
// Exchange the `authorizationCode` for the result
const result = await siwf.getLoginResult(authorizationCode, options);
if (siwf.hasChainSubmissions(result)) {
// Add your own logic for handling the submission to the chain
await processSubmissions(result.payloads);
}
if (result.credentials) {
// Add your own logic for processing credentials
await processCredentials(result.credentials);
}
// Get the ss58 encoded key that identifies this session
// It is also the control key for the user's constant MSA Id
const userKey = result.userPublicKey.encodedValue;
// Add your own logic for session managment
startSession();
}
Step 4: Session Starts
You now have a logged in user! Assuming the chain submissions are complete, you also have:
- A consistent identifier, i.e. the MSA Id
- A universal handle (If the user set one)
- A public delegation between the user's MSA Id and your Provider Id on chain (revokable at any time by you or the user independently)
And if requested:
- Access to the user's private graph
- Permission to act on the user's behalf for delegated actions
- Verified email or phone/SMS number for the user
SIWF Actions
SIWF handles three different situations for each user:
Action | Frequency Blockchain account (MSA) | Delegation with Your Application |
---|---|---|
Create Account | Required | Required |
Create Delegation | Existing | New or Updated Required |
Login | Existing | Existing |
General Flow
- Generate Provider Login Request Payload and Signature (Generator Tool) (Documentation)
- Build and send the user to the Authentication URL (See Details)
- Receive a callback from Frequency Access or other SIWF-compatible services
- Retrieve and process the login response (See Details)
Sequence Diagram
Backend Requirements
- Able to validate payloads received from a SIWF-compatible services
- Able to connect to a Frequency RPC Node
- Able to sign transactions to submit to the Frequency RPC Node
Redirect User to a SIWF-Compatible Service (e.g. Frequency Access)
To start the authentication loop, your application will generate an Authentication URL for each user.
Note: The following instruction examples are based on Frequency Access.
Quick Reference
- Staging-Testnet:
https://testnet.frequencyaccess.com/siwa/start
- Production-Mainnet:
https://www.frequencyaccess.com/siwa/start
- Generate Login Request Payload and Signature: Generator Tool
- Request Structure:
SiwfRequest
- Signed Request Structure:
SiwfSignedRequest
Step 1: Generate the Signed Request Payload
You can generate more than one of these to use simultaneously. Most applications should generate and keep their needed value(s) static. The generated signed request payload is secured by the signature included in it, and it is not sensitive data.
Signed Request Payload Contents
- A signature from one of the Control Keys of the Frequency Provider
- The domain and path the callback will use
- The requested permissions
- The requested credentials
Signed Request Payload Generator
Generate one or more login request payloads and signatures (signedRequest
) using the Generator Tool.
Signed Request Payload Detailed Documentation
For details on the Payload and how it is formed, see the Reference Documentation.
Step 2: Build the Authentication URL Parameters
Parameter: signedRequest
The Base64url encoded value from Step 1.
Reminder: This includes the callback domain that will be used.
Additional Parameters are Forwarded
Any additional parameters that do not collide with reserved parameter names on the Authentication URL are passed through unchanged.
Example
https://www.frequencyaccess.com/siwa/start?signedRequest=<request value>&key1=<value1>&key2=<value2>&other=<result>
- Will result in callback URL parameters of:
?authorizationCode=<authorization code>&key1=<value1>&key2=<value2>&other=<result>
Step 3: Build the Authentication URL
Taking the parameters from the previous step, build an Authentication URL using the correct base for the SIWF path of /start
:
- Staging-Testnet:
https://testnet.frequencyaccess.com/siwa/start
- Production-Mainnet:
https://www.frequencyaccess.com/siwa/start
The SIWF System will send the user back by building the callback URL. The callback URL will be built with:
- The callback from the
signedRequest
- Appending any additional GET request parameters
- Appending the reserved URL parameter of
authorizationCode
The callback URL will maintain all non-reserved URL parameters. For example, if you wish to correlate the original unauthorized session with the authorized session, you can generate a dynamic parameter with a random UUIDv4 identifier on each request.
Example
Parameters
{
"signedRequest": "eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDk2MGYxOTVkYzFmOTFiZjcxYzBiMzUyMzE1MGFlMzc0NzFiZWRlMDdhMDAzOTA5NjQ3Y2NmMDQwYWNkNWNkMDRlYTQ4NzBiZDEyNGNhZmEyZGViNTliMGUzNzhjYjE5ZmJjNmFmNjAxYjc1NTU5ZmFhYjdiNzY4ZGU4MWEwOTgzIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0",
"mode": "dark"
}
Testnet Authentication URL
"https://testnet.frequencyaccess.com/siwa/start?signedRequest=eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDk2MGYxOTVkYzFmOTFiZjcxYzBiMzUyMzE1MGFlMzc0NzFiZWRlMDdhMDAzOTA5NjQ3Y2NmMDQwYWNkNWNkMDRlYTQ4NzBiZDEyNGNhZmEyZGViNTliMGUzNzhjYjE5ZmJjNmFmNjAxYjc1NTU5ZmFhYjdiNzY4ZGU4MWEwOTgzIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0&mode=dark"
Step 3: Redirect the User
- Redirect the user's Browser or Embedded Browser (for mobile apps) to the Authentication URL.
Getting the Login Result from SIWF
After the user completes the authentication and authorization, the user is redirected to the callback URL with one additional parameter set: authorizationCode
.
The authorizationCode
can be used to retrieve the result of the login.
Note: The following instruction examples are based on Frequency Access.
Quick Reference
- Staging-Testnet:
https://testnet.frequencyaccess.com/siwa/api/payload
- Production-Mainnet:
https://www.frequencyaccess.com/siwa/api/payload
- Response Structure:
SiwfResponse
Step 1: Retrieve the Response
GET
:- Staging-Testnet:
https://testnet.frequencyaccess.com/siwa/api/payload?authorizationCode=[Parameter from callback URL]
- Production-Mainnet:
https://www.frequencyaccess.com/siwa/api/payload?authorizationCode=[Parameter from callback URL]
- Staging-Testnet:
Step 2: Parsing the Response
Response Sections
userPublicKey
: The key for the user signing this requestpayloads
: Signed payloads from the usercredentials
: User approved verified credentials from Frequency Access (or other SIWF-compatible services) such as email, phone, user keys, etc...
userPublicKey
The public key for the user identifies the user for this session.
If that user has a Frequency blockchain account (MSA), the MSA Id can be retrieved from Frequency using this key.
Or in the case when it does not, the payloads
section will contain the payload to create said MSA Id.
While the userPublicKey
may change, the MSA Id will always be the same for the same user account.
Step 3: Processing the Credentials
The credentials
array will contain any requested and approved credentials.
Each credential would be matched based on the type
field.
These credentials follow the DSNP Verifiable Credentials Specification.
@dsnp/verifiable-credentials
TypeScript library for verifying these DSNP Credentials specifically- Other W3C Verifiable Credentials verifiers may also be compatable.
Verify the Credential
Trust Model Note: You may choose to just trust credentials issued by Frequency Access (or other SIWF-compatible services) given that the credential is fetched directly. These will have issuer did:web:testnet.frequencyaccess.com
or did:web:frequencyaccess.com
.
- Check that the
credentialSubject.id
matches theuserPublicKey
following thedid:key
Method from the W3C
- Example:
f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH
is the SS58 version with prefix90
of the hex address0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
.0xef01d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
is multicodecsr25519-pub
hex which is multiformatbase58-btc
z6QNzHod3tSSJbwo4e5xGDcnsndsR9WByZzPoCGdbv3sv1jJ
- Fetch the issuer DID Document following the
did:web
Method from the W3C
- Production-Mainnet should always be
did:web:frequencyaccess.com
which resolves tohttps://frequencyaccess.com/.well-known/did.json
- Staging-Testnet should always be
did:web:testnet.frequencyaccess.com
which resolves tohttps://testnet.frequencyaccess.com/.well-known/did.json
- Check that the key in the
proof.verificationMethod
is in the DID Document to verify that the key is still valid - Test that the
proof
validates according the to W3C Verifiable Credentials Specification
Graph Encryption Key Credential
If the user has permitted access to their private social graph per the request for VerifiedGraphKeyPairCredential
, credentials
will have a entry with type
including VerifiedGraphKeyPairCredential
.
This is an x25519
key pair for use with the curve25519xsalsa20poly1305
encryption algorithm from the NaCl Library.
For more information on how the Graph data is structured after decryption, see the DSNP Specification.
This key pair is PII and should be stored with care, but must be stored to read the user's private graph.
Example Credential
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedPhoneNumberCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedPhoneNumberCredential/bciqjspnbwpc3wjx4fewcek5daysdjpbf5xjimz5wnu5uj7e3vu2uwnq.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"phoneNumber": "+01-234-867-5309",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z5sJ2CjHX1wwgzfFGoZNocxeFKd2ffpo5TVgUvdaSkYq1M6gF7UjpYfePo97QoZgmiWdgPAWPjxFvGBysaxHV8DZ4"
}
}
Step 4: Processing the Payloads
The payload section has several different types that can be returned:
login
: When the user already has a correct delegationaddProvider
*: When the user does not have a delegation (a new user signup) or when the delegation was needing to be changeditemActions
*: When the user has user chain data to set or updateclaimHandle
*: When the user needs to claim a new handle
* Requires submission to Frequency
The payloads that require submission to Frequency should be submitted in one batch using Capacity.
The addProvider
must always be first in the batch to ensure the correct permissions and delegations are in place for subsequent actions in the batch.
Signatures to Frequency have an expiration set to a future Frequency block number. If the actions are not submitted before expriation, Frequency will reject the transactions and your application will need to request new signatures.
Payload Examples and Signature Details
login
The correct delegation for the user already exists. No submission to the chain is required, but the application must validate the signature to be sure that the user is authenticated.
The message signed follows CAIP-122: Sign in With X specification which is derived from EIP-4361: Sign-In with Ethereum.
Example Message with Placeholders
{{domain}} wants you to sign in with your Frequency account:
frequency:{{chainReference}}:{{ss58Address}}
URI: {{uri}}
Version: {{version}}
Nonce: {{nonce}}
Chain ID: frequency:{{chainReference}}
Issued At: {{issued-at}}
Inside the message, {{domain}}
is the domain of the application requesting the sign-in. {{domain}}
should match the domain contained in the URI
field.
Validation Steps
- Perform an Sr25519 signature verification using:
userPublicKey
: The signing keypayload.message
: The signed message parsing\n
intoLF
line breakssignature.encodedValue
: The signature
- Verify that the
userPublicKey
matches the second line of the message for the correct chain identifier- Production-Mainnet:
frequency:mainnet:
- Staging-Testnet:
frequency:testnet-paseo:
- Production-Mainnet:
- Verify that the message starts with your domain based on RFC 4501
dnsauthority
- Verify the
Issued At
value from the message is within your acceptable time range - Verify that
Nonce
value in the message is not being reused
Parsing the Message Data
- Break the lines by
\n
- Match based on the prefix:
Nonce:
Issued At:
URI:
addProvider
The user either needs a new delegation or a new MSA created with the delegation.
The endpoint.extrinsic
field will distinguish between the two:
createSponsoredAccountWithDelegation
: New MSAgrantDelegation
: New/Updated Delegation
See Frequency Documentation on forming the transaction for the extrinsics.
itemActions
Item actions will update the user's chain data for things such as their public key for the encrypted graph. These actions must be submitted to the chain for the correct functioning of private graph and other systems.
See Frequency Documentation on forming the transaction for the extrinsics.
claimHandle
The user wishes to claim a Frequency Handle.
See Frequency Documentation on forming the transaction for the extrinsics.
Step 6: Frequency Transaction Submission
All payloads that are returned will be able to be processed using Capacity on Frequency.
Frequency submission is required for any of the following payloads:
addProvider
itemActions
claimHandle
They can be submitted to the chain in one transaction using pay_with_capacity_batch_all
.
Step 6: Session Starts
Once the payloads have been validated, the user's authenticated session may start. SIWF services do not manage user sessions.
Examples
New Frequency User Response
{
"userPublicKey": {
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"payloads": [
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x1a27cb6d79b508e1ffc8d6ae70af78d5b3561cdc426124a06f230d7ce70e757e1947dd1bac8f9e817c30676a5fa6b06510bae1201b698b044ff0660c60f18c8a"
},
"endpoint": {
"pallet": "msa",
"extrinsic": "createSponsoredAccountWithDelegation"
},
"type": "addProvider",
"payload": {
"authorizedMsaId": 1,
"schemaIds": [
5,
7,
8,
9,
10
],
"expiration": 24
}
},
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x9eb338773b386ded2e3731ba68ba734c80408b3ad24f92ed3c60342d374a32293851fa8e41d722c72a5a4e765a9e401c68570a8c666ab678e4e5d94aa6825d85"
},
"endpoint": {
"pallet": "statefulStorage",
"extrinsic": "applyItemActionsWithSignatureV2"
},
"type": "itemActions",
"payload": {
"schemaId": 7,
"targetHash": 0,
"expiration": 20,
"actions": [
{
"type": "addItem",
"payloadHex": "0x40eea1e39d2f154584c4b1ca8f228bb49ae5a14786ed63c90025e755f16bd58d37"
}
]
}
},
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0xb004140fd8ba3395cf5fcef49df8765d90023c293fde4eaf2e932cc24f74fc51b006c0bebcf31d85565648b4881fa22115e0051a3bdb95ab5bf7f37ac66f798f"
},
"endpoint": {
"pallet": "handles",
"extrinsic": "claimHandle"
},
"type": "claimHandle",
"payload": {
"baseHandle": "ExampleHandle",
"expiration": 24
}
}
],
"credentials": [
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedEmailAddressCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedEmailAddressCredential/bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"emailAddress": "john.doe@example.com",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z4jArnPwuwYxLnbBirLanpkcyBpmQwmyn5f3PdTYnxhpy48qpgvHHav6warjizjvtLMg6j3FK3BqbR2nuyT2UTSWC"
}
},
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedGraphKeyCredential",
"VerifiableCredential"
],
"issuer": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedGraphKeyCredential/bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"encodedPublicKeyValue": "0xb5032900293f1c9e5822fd9c120b253cb4a4dfe94c214e688e01f32db9eedf17",
"encodedPrivateKeyValue": "0xd0910c853563723253c4ed105c08614fc8aaaf1b0871375520d72251496e8d87",
"encoding": "base16",
"format": "bare",
"type": "X25519",
"keyType": "dsnp.public-key-key-agreement"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:z6MktZ15TNtrJCW2gDLFjtjmxEdhCadNCaDizWABYfneMqhA",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z2HHWwtWggZfvGqNUk4S5AAbDGqZRFXjpMYAsXXmEksGxTk4DnnkN3upCiL1mhgwHNLkxY3s8YqNyYnmpuvUke7jF"
}
}
]
}
New Application/Delegation Response
{
"userPublicKey": {
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"payloads": [
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0xbac399831b9e3ad464a16e62ad1252cc8344a2c52f80252b2aa450a06ae2362f6f4afcaca791a81f28eaa99080e2654bdbf1071a276213242fc153cca43cfa8e"
},
"endpoint": {
"pallet": "msa",
"extrinsic": "grantDelegation"
},
"type": "addProvider",
"payload": {
"authorizedMsaId": 1,
"schemaIds": [
5,
7,
8,
9,
10
],
"expiration": 24
}
}
],
"credentials": [
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedEmailAddressCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedEmailAddressCredential/bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"emailAddress": "john.doe@example.com",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z4jArnPwuwYxLnbBirLanpkcyBpmQwmyn5f3PdTYnxhpy48qpgvHHav6warjizjvtLMg6j3FK3BqbR2nuyT2UTSWC"
}
},
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedGraphKeyCredential",
"VerifiableCredential"
],
"issuer": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedGraphKeyCredential/bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"encodedPublicKeyValue": "0xb5032900293f1c9e5822fd9c120b253cb4a4dfe94c214e688e01f32db9eedf17",
"encodedPrivateKeyValue": "0xd0910c853563723253c4ed105c08614fc8aaaf1b0871375520d72251496e8d87",
"encoding": "base16",
"format": "bare",
"type": "X25519",
"keyType": "dsnp.public-key-key-agreement"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:z6MktZ15TNtrJCW2gDLFjtjmxEdhCadNCaDizWABYfneMqhA",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z2HHWwtWggZfvGqNUk4S5AAbDGqZRFXjpMYAsXXmEksGxTk4DnnkN3upCiL1mhgwHNLkxY3s8YqNyYnmpuvUke7jF"
}
}
]
}
Login Only Response
{
"userPublicKey": {
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"payloads": [
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0xe261698297111834e68b4152bf1f89819e886b6528f6fff45715f7781d0f1e7dc4007ccfed1e85b8c603c0fea2f7abf22bfe6336869ad21f11a09a114452c680"
},
"type": "login",
"payload": {
"message": "your-app.com wants you to sign in with your Frequency account:\nf6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ\n\n\n\nURI: https://your-app.com/signin/callback\nNonce: N6rLwqyz34oUxJEXJ\nIssued At: 2024-10-29T19:17:27.077Z\nExpiration Time: 2060-03-05T23:23:03.041Z"
}
}
],
"credentials": [
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedEmailAddressCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedEmailAddressCredential/bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"emailAddress": "john.doe@example.com",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z4jArnPwuwYxLnbBirLanpkcyBpmQwmyn5f3PdTYnxhpy48qpgvHHav6warjizjvtLMg6j3FK3BqbR2nuyT2UTSWC"
}
},
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedGraphKeyCredential",
"VerifiableCredential"
],
"issuer": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedGraphKeyCredential/bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"encodedPublicKeyValue": "0xb5032900293f1c9e5822fd9c120b253cb4a4dfe94c214e688e01f32db9eedf17",
"encodedPrivateKeyValue": "0xd0910c853563723253c4ed105c08614fc8aaaf1b0871375520d72251496e8d87",
"encoding": "base16",
"format": "bare",
"type": "X25519",
"keyType": "dsnp.public-key-key-agreement"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:z6MktZ15TNtrJCW2gDLFjtjmxEdhCadNCaDizWABYfneMqhA",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z2HHWwtWggZfvGqNUk4S5AAbDGqZRFXjpMYAsXXmEksGxTk4DnnkN3upCiL1mhgwHNLkxY3s8YqNyYnmpuvUke7jF"
}
}
]
}
Reference
- Signature Generation
- Available Credentials
- Available Delegations
- Signed Payloads
- Data Structures and Examples
Authentication URL Signature
Most applications skip all of this and just generate the login request payload and signature.
Step 1: Create the Payload for Signing
Parameter: callback
When the user has completed the authentication, this is the return URI that will be used.
Appended to the URL will be this parameter:
authorizationCode
Used to retrieve the full response payload
The callback url will maintain any other URL parameters included. For example, if you wish to correlate the original unauthorized session with the authorized session, you can generate a dynamic callback url with a parameter with a random UUIDv4 identifier on each request.
Parameter: permissions
The list of Frequency Schema Ids permissions your application is requesting from the user.
- See a full list of Available Delegations
Parameter: userIdentifierAdminUrl
Only used for custom integration situations.
Step 2: Signing the Request
To ensure that the correct application is requesting the authentication and that the response is only sent to the authorized party, the request is signed. The signature MUST be from one of the Control Keys of the Frequency Provider.
2a: Serialize the payload using the SCALE Codec
SCALE Type (Note: Order matters!)
{
"callback": "String",
"permissions": "Vec<U16>",
"userIdentifierAdminUrl": "Option<String>",
}
2b: Wrap the Payload
So that no payloads can be accidentally used on a chain, the payload is wrapped with a <Bytes>
tag.
Byte Arrays Concatenated: [ 60, 66, 121, 116, 101, 115, 62 ] + scale_encoded_payload_bytes + [ 60, 47, 66, 121, 116, 101, 115, 62 ]
2c: Sign the Wrapped Payload Bytes
Sign the serialized payload using Schnorr signatures over ECDSA.
2d: Example
Remember that SR25519 signatures are non-deterministic, so the payload and encoding will match, but the signature will be different.
This example uses the //Alice
seed phrase to generate the signature.
- Payload:
{ "callback": "https://localhost:44181", "permissions": [5, 7, 8, 9, 10] }
- SCALE Payload (Hex):
0x5c68747470733a2f2f6c6f63616c686f73743a34343138311405000700080009000a0000
- Wrapped Payload (Hex):
0x3c42797465733e5c68747470733a2f2f6c6f63616c686f73743a34343138311405000700080009000a00003c2f42797465733e
- Signing Public Key (SS58 Prefix 90):
f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH
- Signature (Hex):
0x9abd3c54e7164e8385627dc692724b9467386acd7b02a13d6187e2c58fd91440d9134781c0410a45812f5532b71f4a34b4a5443ef8d68b5a1956f7f0f81d4286
Step 3 (Optional): Request Credentials (Graph Key, Email, Phone)
Frequency Access users can provide verified email or phone/SMS to your application when requested and approved by the user. This is not required, and best practice is to only make such a request if it is required for the functioning of the application.
The request MUST be wrapped in requestedCredentials
which is an array that requires ALL listed credential objects.
Supported Options:
anyOf
: Request for one or more credentials from the list (0+ may return)
{
// ...
"requestedCredentials": [
{
"type": "VerifiedGraphKeyCredential",
"hash": ["bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y"]
}
{
"anyOf": [
// List of contact credential requests here
{
"type": "VerifiedEmailAddressCredential",
"hash": ["bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi"]
},
{
"type": "VerifiedPhoneNumberCredential",
"hash": ["bciqjspnbwpc3wjx4fewcek5daysdjpbf5xjimz5wnu5uj7e3vu2uwnq"]
}
]
}
]
}
- See a full list of Available Credentials
Example Using TypeScript/JavaScript
// This is the URI of a key. Usually just a seed phrase, but also supports test accounts such as `//Alice` or `//Bob`
const providerKeyUri: string = getProviderKeyUriSecret();
// The list of Frequency Schemas Ids that you are requesting the user delegate
// See a full reference: https://projectlibertylabs.github.io/siwf/v2/docs/Delegations.html
// This example is for Graph Only
const permissions: number[] = [7, 8, 9, 10];
// List of Credentials
// See a full reference and examples: https://projectlibertylabs.github.io/siwf/v2/docs/Credentials.html
const credentials = [
{
anyOf: [siwf.VerifiedEmailAddressCredential, siwf.VerifiedPhoneNumberCredential],
},
siwf.VerifiedGraphKeyCredential,
];
// This is the URI that the user should return to after authenticating
const callbackUri: string = getWebOrApplicationCallbackUri();
// The Encoded Signed Request can remain static if
// It is the same as is generated with the Signed Payload Generation Tool
const encodedSignedRequest = await siwf.generateEncodedSignedRequest(
providerKeyUri,
callbackUri,
permissions,
credentials,
);
// Options with endpoint selection
// Endpoint may be tagged or specified in full
const options = { endpoint: "production" };
// Staging-Testnet Options
// const options = { endpoint: 'staging' };
const authenticationUrl: string = generateAuthenticationUrl(signedRequest, new URLSearchParams({ id: getSessionId() }));
Full Example Request
{
"requestedSignatures": {
"publicKey": {
"encodedValue": "f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x0407ce814b77861df94d16b3fcb317d37a07abc2a7f9cd7c02cc22529ee7b32d56795f88bd6b4ad106b72b91b6246a783671bcd24cb01aaf0e9316db5e0cd085"
},
"payload": {
"callback": "http://localhost:3000",
"permissions": [
5,
7,
8,
9,
10
]
}
},
"requestedCredentials": [
{
"type": "VerifiedGraphKeyCredential",
"hash": [
"bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y"
]
},
{
"anyOf": [
{
"type": "VerifiedEmailAddressCredential",
"hash": [
"bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi"
]
},
{
"type": "VerifiedPhoneNumberCredential",
"hash": [
"bciqjspnbwpc3wjx4fewcek5daysdjpbf5xjimz5wnu5uj7e3vu2uwnq"
]
}
]
}
]
}
Usage
See Start for details on how to use the generated signature.
Serialization
- JSON Stringify the
SignedRequest
object base64url
encode the stringified result
Signed Request Generator
Fill out the form and the signed request will be generated at the bottom.
Result
- Login Request Payload and Signature (
signedRequest
parameter ) - Mainnet/Production URL
- Testnet/Staging URL
- Signed Request (JSON)
Expand
Credentials
Request Structure
The request is an array that requires ALL listed credential objects. Supported Options:
anyOf
: Request for one or more credentials from the list (0+ may return)
Example Request
This is a common request: one verified contact method and access to the graph encryption key.
[
{
"type": "VerifiedGraphKeyCredential",
"hash": ["bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y"]
},
{
"anyOf": [
{
"type": "VerifiedEmailAddressCredential",
"hash": ["bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi"]
},
{
"type": "VerifiedPhoneNumberCredential",
"hash": ["bciqjspnbwpc3wjx4fewcek5daysdjpbf5xjimz5wnu5uj7e3vu2uwnq"]
}
]
}
]
Available Credentials
Each request also has a multiformat hash of the schema file to ensure the correct verification document is requested. Below are the official types and multihashes to use.
Graph Key
{
"type": "VerifiedGraphKeyCredential",
"hash": ["bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y"]
}
{
"type": "VerifiedEmailAddressCredential",
"hash": ["bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi"]
}
Phone/SMS
{
"type": "VerifiedPhoneNumberCredential",
"hash": ["bciqjspnbwpc3wjx4fewcek5daysdjpbf5xjimz5wnu5uj7e3vu2uwnq"]
}
Available Delegations
Staging-Testnet and Production-Mainnet have the same delegation Schema Ids available.
Short Name and Specification Link | Description | Schema Id |
---|---|---|
dsnp.broadcast@v1 | (Deprecated) Create new public content | 2 |
dsnp.broadcast@v2 | Create new public content | 17 |
dsnp.dsnp-content-attribute@v1 | Create an authenticated attribute set for DSNP content | 12 |
dsnp.ext-content-attribute@v1 | Create an authenticated attribute set for content external to DSNP | 13 |
dsnp.private-connections@v1 | Update private friendship connections | 10 |
dsnp.private-follows@v1 | Update private follow list | 9 |
dsnp.profile-resources@v1 | Update user profile information | 15 |
dsnp.profile@v1 | (Deprecated) Update profile information | 6 |
dsnp.public-follows@v1 | Update public follow list | 8 |
dsnp.reaction@v1 | Public reaction to content | 4 |
dsnp.reply@v1 | (Deprecated) Public reply to content | 3 |
dsnp.reply@v2 | Public reply to content | 18 |
dsnp.tombstone@v1 | (Deprecated) Mark content for deletion | 1 |
dsnp.tombstone@v2 | Mark content for deletion | 16 |
dsnp.update@v1 | (Deprecated) Update an existing post or reply | 5 |
dsnp.update@v2 | Update an existing post or reply | 19 |
dsnp.user-attribute-set@v2 | Create an authenticated attribute set for a DSNP User | 20 |
Possible Payloads
Each response may have one or more of the following signed payloads.
Login
The signature is generated by signing the UTF-8 bytes of payload.message
using SR25519
.
See Response Payloads: Login for more details.
Example
Example is signed using f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ
which is the SS58 (Prefix 90) public key from the seed phrase //Bob
.
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x84a4e03344b07d64087ebdf47b2c8c679aa7de78179689988992609f1b83c34f6086c7de99ef41c5325cce64d148624e716c605d355f22d1281f6d23f546f584"
},
"type": "login",
"payload": {
"message": "localhost wants you to sign in with your Frequency account:\nf6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ\n\n\n\nURI: https://testnet.frequencyaccess.com/signin/confirm\nNonce: N6rLwqyz34oUxJEXJ\nIssued At: 2024-03-05T23:18:03.041Z\nExpiration Time: 2060-03-05T23:23:03.041Z"
}
}
Add Provider
This payload follows the AddProvider
type from Frequency.
It has the same payload for two different endpoint extrinsics: createSponsoredAccountWithDelegation
used for creating a new MSA on chain and grantDelegation
which is used to grant a new provider permissions on an existing MSA.
The signature is generated by signing the SCALE-encoded payload using SR25519
.
Example
Example is signed using f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ
which is the SS58 (Prefix 90) public key from the seed phrase //Bob
.
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x94156d570b29e9c4e3a04eefbff56439f40de7fb6bdba1ca31e9017b55e5e773f747d0ab4f0fc2b44ca903aa8fb641f227fac395e74bb1d837d07cfa70fa1e80"
},
"endpoint": {
"pallet": "msa",
"extrinsic": "grantDelegation"
},
"type": "addProvider",
"payload": {
"authorizedMsaId": 1,
"schemaIds": [
5,
7,
8,
9,
10
],
"expiration": 24
}
}
SCALE Payload Type
{
authorizedMsaId: 'u64',
schemaIds: 'Vec<u16>',
expiration: 'u32',
}
Claim Handle
This payload follows the ClaimHandlePayload
type from Frequency.
The signature is generated by signing the SCALE-encoded payload using SR25519
.
Example
Example is signed using f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ
which is the SS58 (Prefix 90) public key from the seed phrase //Bob
.
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0xc8c7587ef80b6bd64295d63b69f97196a9a0b635bd8f1974156d7e3c7206134bb9838d29978a2f91c18a6592aff180f2314db7528b6aac796f0073d758406e81"
},
"endpoint": {
"pallet": "handles",
"extrinsic": "claimHandle"
},
"type": "claimHandle",
"payload": {
"baseHandle": "ExampleHandle",
"expiration": 24
}
}
SCALE Payload Type
{
baseHandle: 'Bytes',
expiration: 'u32',
}
User Item Actions
This payload follows the ItemizedSignaturePayloadV2
type from Frequency.
The signature is generated by signing the SCALE-encoded payload using SR25519
.
Example
Example is signed using f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ
which is the SS58 (Prefix 90) public key from the seed phrase //Bob
.
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x86bdd46a5f91ed3f259374f5856fdc48ee00b8eced10eecd05af8d7637c51d17df6252f617feacbce1cf91cc57ca036c69773ab9b0c31d6843344704b4fb898d"
},
"endpoint": {
"pallet": "statefulStorage",
"extrinsic": "applyItemActionsWithSignatureV2"
},
"type": "itemActions",
"payload": {
"schemaId": 7,
"targetHash": 0,
"expiration": 20,
"actions": [
{
"type": "addItem",
"payloadHex": "0x40eea1e39d2f154584c4b1ca8f228bb49ae5a14786ed63c90025e755f16bd58d37"
}
]
}
}
SCALE Payload Types
{
PalletStatefulStorageItemActionEnumAdd: {
data: 'Bytes',
},
PalletStatefulStorageItemActionEnumDelete: {
index: 'u16',
},
PalletStatefulStorageItemAction: {
_enum: {
Add: '<PalletStatefulStorageItemActionEnumAdd>',
Delete: '<PalletStatefulStorageItemActionEnumDelete>',
},
},
PalletStatefulStorageItemizedSignaturePayloadV2: {
schemaId: 'Compact<u16>',
targetHash: 'Compact<u32>',
expiration: 'u32',
actions: 'Vec<PalletStatefulStorageItemAction>',
},
}
Data Structure Reference
Request / Response from SIWF
Request
{
"signedRequest": "eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDk2MGYxOTVkYzFmOTFiZjcxYzBiMzUyMzE1MGFlMzc0NzFiZWRlMDdhMDAzOTA5NjQ3Y2NmMDQwYWNkNWNkMDRlYTQ4NzBiZDEyNGNhZmEyZGViNTliMGUzNzhjYjE5ZmJjNmFmNjAxYjc1NTU5ZmFhYjdiNzY4ZGU4MWEwOTgzIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0",
"mode": "dark"
}
Request URL
"https://testnet.frequencyaccess.com/siwa/start?signedRequest=eyJyZXF1ZXN0ZWRTaWduYXR1cmVzIjp7InB1YmxpY0tleSI6eyJlbmNvZGVkVmFsdWUiOiJmNmNMNHdxMUhVTngxMVRjdmRBQk5mOVVOWFhveUg0N21WVXdUNTl0elNGUlc4eURIIiwiZW5jb2RpbmciOiJiYXNlNTgiLCJmb3JtYXQiOiJzczU4IiwidHlwZSI6IlNyMjU1MTkifSwic2lnbmF0dXJlIjp7ImFsZ28iOiJTUjI1NTE5IiwiZW5jb2RpbmciOiJiYXNlMTYiLCJlbmNvZGVkVmFsdWUiOiIweDk2MGYxOTVkYzFmOTFiZjcxYzBiMzUyMzE1MGFlMzc0NzFiZWRlMDdhMDAzOTA5NjQ3Y2NmMDQwYWNkNWNkMDRlYTQ4NzBiZDEyNGNhZmEyZGViNTliMGUzNzhjYjE5ZmJjNmFmNjAxYjc1NTU5ZmFhYjdiNzY4ZGU4MWEwOTgzIn0sInBheWxvYWQiOnsiY2FsbGJhY2siOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJwZXJtaXNzaW9ucyI6WzUsNyw4LDksMTBdfX0sInJlcXVlc3RlZENyZWRlbnRpYWxzIjpbeyJ0eXBlIjoiVmVyaWZpZWRHcmFwaEtleUNyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFtZHZteGQ1NHp2ZTVraWZ5Y2dzZHRvYWhzNWVjZjRoYWwydHMzZWV4a2dvY3ljNW9jYTJ5Il19LHsiYW55T2YiOlt7InR5cGUiOiJWZXJpZmllZEVtYWlsQWRkcmVzc0NyZWRlbnRpYWwiLCJoYXNoIjpbImJjaXFlNHFvY3poZnRpY2k0ZHpmdmZiZWw3Zm80aDRzcjVncmNvM29vdnd5azZ5NHluZjQ0dHNpIl19LHsidHlwZSI6IlZlcmlmaWVkUGhvbmVOdW1iZXJDcmVkZW50aWFsIiwiaGFzaCI6WyJiY2lxanNwbmJ3cGMzd2p4NGZld2NlazVkYXlzZGpwYmY1eGppbXo1d251NXVqN2UzdnUydXducSJdfV19XX0&mode=dark"
Signed Request
This is JSON stringified and then base64url
encoded for the Request signedRequest
value.
{
"requestedSignatures": {
"publicKey": {
"encodedValue": "f6cL4wq1HUNx11TcvdABNf9UNXXoyH47mVUwT59tzSFRW8yDH",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x0407ce814b77861df94d16b3fcb317d37a07abc2a7f9cd7c02cc22529ee7b32d56795f88bd6b4ad106b72b91b6246a783671bcd24cb01aaf0e9316db5e0cd085"
},
"payload": {
"callback": "http://localhost:3000",
"permissions": [
5,
7,
8,
9,
10
]
}
},
"requestedCredentials": [
{
"type": "VerifiedGraphKeyCredential",
"hash": [
"bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y"
]
},
{
"anyOf": [
{
"type": "VerifiedEmailAddressCredential",
"hash": [
"bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi"
]
},
{
"type": "VerifiedPhoneNumberCredential",
"hash": [
"bciqjspnbwpc3wjx4fewcek5daysdjpbf5xjimz5wnu5uj7e3vu2uwnq"
]
}
]
}
]
}
New Frequency User Response
{
"userPublicKey": {
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"payloads": [
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x1a27cb6d79b508e1ffc8d6ae70af78d5b3561cdc426124a06f230d7ce70e757e1947dd1bac8f9e817c30676a5fa6b06510bae1201b698b044ff0660c60f18c8a"
},
"endpoint": {
"pallet": "msa",
"extrinsic": "createSponsoredAccountWithDelegation"
},
"type": "addProvider",
"payload": {
"authorizedMsaId": 1,
"schemaIds": [
5,
7,
8,
9,
10
],
"expiration": 24
}
},
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0x9eb338773b386ded2e3731ba68ba734c80408b3ad24f92ed3c60342d374a32293851fa8e41d722c72a5a4e765a9e401c68570a8c666ab678e4e5d94aa6825d85"
},
"endpoint": {
"pallet": "statefulStorage",
"extrinsic": "applyItemActionsWithSignatureV2"
},
"type": "itemActions",
"payload": {
"schemaId": 7,
"targetHash": 0,
"expiration": 20,
"actions": [
{
"type": "addItem",
"payloadHex": "0x40eea1e39d2f154584c4b1ca8f228bb49ae5a14786ed63c90025e755f16bd58d37"
}
]
}
},
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0xb004140fd8ba3395cf5fcef49df8765d90023c293fde4eaf2e932cc24f74fc51b006c0bebcf31d85565648b4881fa22115e0051a3bdb95ab5bf7f37ac66f798f"
},
"endpoint": {
"pallet": "handles",
"extrinsic": "claimHandle"
},
"type": "claimHandle",
"payload": {
"baseHandle": "ExampleHandle",
"expiration": 24
}
}
],
"credentials": [
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedEmailAddressCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedEmailAddressCredential/bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"emailAddress": "john.doe@example.com",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z4jArnPwuwYxLnbBirLanpkcyBpmQwmyn5f3PdTYnxhpy48qpgvHHav6warjizjvtLMg6j3FK3BqbR2nuyT2UTSWC"
}
},
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedGraphKeyCredential",
"VerifiableCredential"
],
"issuer": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedGraphKeyCredential/bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"encodedPublicKeyValue": "0xb5032900293f1c9e5822fd9c120b253cb4a4dfe94c214e688e01f32db9eedf17",
"encodedPrivateKeyValue": "0xd0910c853563723253c4ed105c08614fc8aaaf1b0871375520d72251496e8d87",
"encoding": "base16",
"format": "bare",
"type": "X25519",
"keyType": "dsnp.public-key-key-agreement"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:z6MktZ15TNtrJCW2gDLFjtjmxEdhCadNCaDizWABYfneMqhA",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z2HHWwtWggZfvGqNUk4S5AAbDGqZRFXjpMYAsXXmEksGxTk4DnnkN3upCiL1mhgwHNLkxY3s8YqNyYnmpuvUke7jF"
}
}
]
}
New Application/Delegation Response
{
"userPublicKey": {
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"payloads": [
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0xbac399831b9e3ad464a16e62ad1252cc8344a2c52f80252b2aa450a06ae2362f6f4afcaca791a81f28eaa99080e2654bdbf1071a276213242fc153cca43cfa8e"
},
"endpoint": {
"pallet": "msa",
"extrinsic": "grantDelegation"
},
"type": "addProvider",
"payload": {
"authorizedMsaId": 1,
"schemaIds": [
5,
7,
8,
9,
10
],
"expiration": 24
}
}
],
"credentials": [
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedEmailAddressCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedEmailAddressCredential/bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"emailAddress": "john.doe@example.com",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z4jArnPwuwYxLnbBirLanpkcyBpmQwmyn5f3PdTYnxhpy48qpgvHHav6warjizjvtLMg6j3FK3BqbR2nuyT2UTSWC"
}
},
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedGraphKeyCredential",
"VerifiableCredential"
],
"issuer": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedGraphKeyCredential/bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"encodedPublicKeyValue": "0xb5032900293f1c9e5822fd9c120b253cb4a4dfe94c214e688e01f32db9eedf17",
"encodedPrivateKeyValue": "0xd0910c853563723253c4ed105c08614fc8aaaf1b0871375520d72251496e8d87",
"encoding": "base16",
"format": "bare",
"type": "X25519",
"keyType": "dsnp.public-key-key-agreement"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:z6MktZ15TNtrJCW2gDLFjtjmxEdhCadNCaDizWABYfneMqhA",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z2HHWwtWggZfvGqNUk4S5AAbDGqZRFXjpMYAsXXmEksGxTk4DnnkN3upCiL1mhgwHNLkxY3s8YqNyYnmpuvUke7jF"
}
}
]
}
Login Only Response
{
"userPublicKey": {
"encodedValue": "f6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ",
"encoding": "base58",
"format": "ss58",
"type": "Sr25519"
},
"payloads": [
{
"signature": {
"algo": "SR25519",
"encoding": "base16",
"encodedValue": "0xe261698297111834e68b4152bf1f89819e886b6528f6fff45715f7781d0f1e7dc4007ccfed1e85b8c603c0fea2f7abf22bfe6336869ad21f11a09a114452c680"
},
"type": "login",
"payload": {
"message": "your-app.com wants you to sign in with your Frequency account:\nf6akufkq9Lex6rT8RCEDRuoZQRgo5pWiRzeo81nmKNGWGNJdJ\n\n\n\nURI: https://your-app.com/signin/callback\nNonce: N6rLwqyz34oUxJEXJ\nIssued At: 2024-10-29T19:17:27.077Z\nExpiration Time: 2060-03-05T23:23:03.041Z"
}
}
],
"credentials": [
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedEmailAddressCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedEmailAddressCredential/bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"emailAddress": "john.doe@example.com",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z4jArnPwuwYxLnbBirLanpkcyBpmQwmyn5f3PdTYnxhpy48qpgvHHav6warjizjvtLMg6j3FK3BqbR2nuyT2UTSWC"
}
},
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedGraphKeyCredential",
"VerifiableCredential"
],
"issuer": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedGraphKeyCredential/bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"encodedPublicKeyValue": "0xb5032900293f1c9e5822fd9c120b253cb4a4dfe94c214e688e01f32db9eedf17",
"encodedPrivateKeyValue": "0xd0910c853563723253c4ed105c08614fc8aaaf1b0871375520d72251496e8d87",
"encoding": "base16",
"format": "bare",
"type": "X25519",
"keyType": "dsnp.public-key-key-agreement"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:z6MktZ15TNtrJCW2gDLFjtjmxEdhCadNCaDizWABYfneMqhA",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z2HHWwtWggZfvGqNUk4S5AAbDGqZRFXjpMYAsXXmEksGxTk4DnnkN3upCiL1mhgwHNLkxY3s8YqNyYnmpuvUke7jF"
}
}
]
}
Verified User Data
Graph Key
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedGraphKeyCredential",
"VerifiableCredential"
],
"issuer": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedGraphKeyCredential/bciqmdvmxd54zve5kifycgsdtoahs5ecf4hal2ts3eexkgocyc5oca2y.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"encodedPublicKeyValue": "0xb5032900293f1c9e5822fd9c120b253cb4a4dfe94c214e688e01f32db9eedf17",
"encodedPrivateKeyValue": "0xd0910c853563723253c4ed105c08614fc8aaaf1b0871375520d72251496e8d87",
"encoding": "base16",
"format": "bare",
"type": "X25519",
"keyType": "dsnp.public-key-key-agreement"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:z6MktZ15TNtrJCW2gDLFjtjmxEdhCadNCaDizWABYfneMqhA",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z2HHWwtWggZfvGqNUk4S5AAbDGqZRFXjpMYAsXXmEksGxTk4DnnkN3upCiL1mhgwHNLkxY3s8YqNyYnmpuvUke7jF"
}
}
Verified Contact Credentials
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedEmailAddressCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedEmailAddressCredential/bciqe4qoczhftici4dzfvfbel7fo4h4sr5grco3oovwyk6y4ynf44tsi.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"emailAddress": "john.doe@example.com",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z4jArnPwuwYxLnbBirLanpkcyBpmQwmyn5f3PdTYnxhpy48qpgvHHav6warjizjvtLMg6j3FK3BqbR2nuyT2UTSWC"
}
}
SMS/Phone
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/undefined-terms/v2"
],
"type": [
"VerifiedPhoneNumberCredential",
"VerifiableCredential"
],
"issuer": "did:web:frequencyaccess.com",
"validFrom": "2024-08-21T21:28:08.289+0000",
"credentialSchema": {
"type": "JsonSchema",
"id": "https://schemas.frequencyaccess.com/VerifiedPhoneNumberCredential/bciqjspnbwpc3wjx4fewcek5daysdjpbf5xjimz5wnu5uj7e3vu2uwnq.json"
},
"credentialSubject": {
"id": "did:key:z6QNucQV4AF1XMQV4kngbmnBHwYa6mVswPEGrkFrUayhttT1",
"phoneNumber": "+01-234-867-5309",
"lastVerified": "2024-08-21T21:27:59.309+0000"
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:web:frequencyaccess.com#z6MkofWExWkUvTZeXb9TmLta5mBT6Qtj58es5Fqg1L5BCWQD",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z5sJ2CjHX1wwgzfFGoZNocxeFKd2ffpo5TVgUvdaSkYq1M6gF7UjpYfePo97QoZgmiWdgPAWPjxFvGBysaxHV8DZ4"
}
}