- NexeraID Identity SDK, written in TypeScript.
npm install @nexeraid/identity-sdk
- You need to provide NexeraID Team with the Web App domain and a Webhook
- You need to provide NexeraID with the required rules
- NexeraID Team will provide to you with an API_KEY and a RULE_ID
/*
* Get access token
* This has to be done from secured server, to avoid leaking API_KEY
*/
const response = await fetch('https://api.nexera.id/kyc/auth/access-token', {
body: JSON.stringify({ address }),
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
method: 'POST'
})
const { accessToken } = await response.json()
/*
* Handle data from webhook
* At the defined webhook endpoint, each time an user shares data with you, data with format
* {
* address: '0x0000000000000000000000000000000000000000',
* data: {
* ...
* }
* }
*/
// Assuming you have this data in some variable named input
const response = await fetch('https://api.nexera.id/compliance/rules/execute', {
body: JSON.stringify({
inputData: input.data,
address: input.address,
policyId: `${POLICY_ID}`,
}),
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
method: 'POST'
})
/*
* Validation result structure could vary according the required rules defined, but it will
* have the necessary flags that determine whether or not the user meets the requirements.
*/
const validationResult = await response.json()
// instantiate IdentityClient
const IDENTITY_CLIENT = new IdentityClientV2({
env: "prod"
});
// or
// default value is prod
const IDENTITY_CLIENT = new IdentityClientV2();
// configure identity flow callbacks
// mandatory onSignPersonalData callback
IDENTITY_CLIENT.onSignMessage(async (data: string) => {
// make user sign data with wallet, and return result
return await signMessageAsync({message: data})
})
// (optional) Sign a transaction sended to the client, required to retunr the txHash
IDENTITY_CLIENT.onSendTransaction(async (data) => {
return await walletClient?.sendTransaction({
account: data.accountAddress as Address,
to: data.to as Address,
data: data.data as Address,
value: data.value ? parseEther(data.value) : parseEther("0"),
});
});
// build signing message, needed to safety store identity in user's browser, and address should be in lowercase, to allow compatibility cross applications
const signingMessage = IdentityClientV2.buildSignatureMessage(address)
const signature = await signMessageAsync({message: signingMessage})
// here you need to get access token from your server, which will call our backend as we explained in the Server app section
const accessToken = getAccessTokenFromYourServer(address)
// Initialize iframe (hidden) with ky-app and starts listening for events
await IDENTITY_CLIENT.init({
accessToken: kycAuth.accessToken,
signature: kycAuth.signature,
signingMessage: kycAuth.signingMessage,
})
const isAllowed = await IDENTITY_CLIENT.isUserAllowedForEntrypoint(userAddress);
IDENTITY_CLIENT.onVerification((isAllowed) => {
setVerified(isAllowed);
});
This endpoint is used to retrieve a signature from the Nexera API in order to authorize a contract call gated with our Tx Auth Data Signature feature.
// Tx Auth Input
// with our example Gated NFT Minter
const txAuthInput = {
contractAbi: ExampleGatedNFTMinterABI,
contractAddress: ExampleGatedNFTMinterAddress_polygonAmoy,
functionName: "mintNFTGated",
args: [recipientAddress],
chainId,
// optional inputs, useful for testing with a local network
blockExpiration,
nonce
};
// Get signature Response
const signatureResponse: GetTxAuthDataSignatureResponse = await IDENTITY_CLIENT.getTxAuthSignature(txAuthInput);
// This is what the response looks
export const GetTxAuthDataSignatureResponse = z.object({
signature: Signature.optional(),
blockExpiration: z.number().optional(),
isAuthorized: z.boolean(),
});
export type GetTxAuthDataSignatureResponse = z.infer<
typeof GetTxAuthDataSignatureResponse
>;
Make sure to run the init flow before this.
const credentials = await IDENTITY_CLIENT.getStoredCredentials(
{ type: "getCredentials", data: undefined }, // data will be able to add filters later
);
Note: the following functions follow the iden3comm standard https://0xpolygonid.github.io/tutorials/wallet/wallet-sdk/polygonid-sdk/iden3comm/overview/
auth handles AuthorizationRequestMessage
:
generates a zk-request for the given inputs and
automatically calls verify endpoint
with zk-proof generated with the wallet
import type { AuthorizationRequestMessage } from "@unblokttechnology/nexera-id-schemas";
const authRequest: AuthorizationRequestMessage = {...}
await IDENTITY_CLIENT.polygonIdRequest(
{ type: "auth", authRequest}
);
credentialRequest ZeroKnowledgeProofRequest
:
generates a zk-request for the given inputs
import type {ZKPRequest} from "@unblokttechnology/nexera-id-schemas";
const zkpRequest: ZKPRequest = {...}
await IDENTITY_CLIENT.polygonIdRequest(
{type: "zkp", zkpRequest: zkpRequest}
);
credentialOffer handles CredentialOffer object in string format: adds a crdential to the polygon wallet (sent from a third party)
const authRequest:string="{...}"
await IDENTITY_CLIENT.polygonIdRequest(
{ type: "credentialOffer", credentialOfferRequest }
);
Make sure to run the init flow before this
// finally, once accessToken, signingMessage and signature ready, IdentityClient flow can be triggered
IDENTITY_CLIENT.startVerification();
IDENTITY_CLIENT.startManagement();