UNPKG

@didtools/pkh-tezos

Version:

Implements support to authenticate, authorize and verify with Tezos accounts as a did:pkh with SIWE(X) and CACAO. Primarly used with `did-session` and `@didtools/cacao`.

94 lines (93 loc) 3.55 kB
import { AccountId } from 'caip'; import { randomString } from '@stablelib/random'; import { Cacao, SiwTezosMessage } from '@didtools/cacao'; export const TEZOS_MAINNET_CHAIN_REF = 'NetXdQprcVkpaWU' // Tezos mainnet ; export const TEZOS_DEVNET_CHAIN_REF = 'NetXm8tYqnMWky1' // Tezos devnet ; export const VERSION = '1'; export const CHAIN_NAMESPACE = 'tezos'; export const chainIdMap = { mainnet: TEZOS_MAINNET_CHAIN_REF, devnet: TEZOS_DEVNET_CHAIN_REF }; export var TezosWebAuth; (function(TezosWebAuth) { async function getAuthMethod(tzProvider, account) { if (typeof window === 'undefined') throw new Error('Web Auth method requires browser environment'); const domain = window.location.hostname; return async (opts)=>{ opts.domain = domain; return createCACAO(opts, tzProvider, account); }; } // eslint-disable-next-line @typescript-eslint/require-await TezosWebAuth.getAuthMethod = getAuthMethod; })(TezosWebAuth || (TezosWebAuth = {})); export function assertSupportedProvider(tzProvider) { const p = tzProvider; if (p.requestSignPayload == null) { throw new Error('Unsupported provider; provider must implement requestSignPayload'); } } export function assertSupportedConnection(tzProvider) { const c = tzProvider; if (c.getActiveAccount === null || c.getActiveAccount === undefined) { throw new Error(`Unsupported provider; provider must implement getActiveAccount`); } } async function sign(tzProvider, message) { assertSupportedProvider(tzProvider); const { signature } = await tzProvider.requestSignPayload({ signingType: 'micheline', payload: message }); return signature; } async function createCACAO(opts, tzProvider, account) { const now = new Date(); const oneWeekLater = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); const siwTezosMessage = new SiwTezosMessage({ domain: opts.domain, address: account.address, statement: opts.statement ?? 'Give this application access to some of your data on Ceramic', uri: opts.uri, version: VERSION, nonce: opts.nonce ?? randomString(10), issuedAt: now.toISOString(), expirationTime: opts.expirationTime ?? oneWeekLater.toISOString(), chainId: account.chainId.reference, resources: opts.resources }); const signData = siwTezosMessage.signMessage(); const signature = await sign(tzProvider, signData); const publicKey = await getPublicKey(tzProvider); siwTezosMessage.signature = signature + publicKey; return Cacao.fromSiwTezosMessage(siwTezosMessage); } export async function requestChainId(tzProvider) { assertSupportedConnection(tzProvider); const activeAccount = await tzProvider.getActiveAccount(); const network = activeAccount.network.type; return chainIdMap[network]; } export async function getAccountId(tzProvider, address) { const tezosChainId = await requestChainId(tzProvider); const chainId = `${CHAIN_NAMESPACE}:${tezosChainId}`; return new AccountId({ address, chainId }); } export function getAccountIdByNetwork(network, address) { const chainId = `${CHAIN_NAMESPACE}:${chainIdMap[network]}`; return new AccountId({ address, chainId }); } export async function getPublicKey(tzProvider) { assertSupportedConnection(tzProvider); const activeAccount = await tzProvider.getActiveAccount(); return activeAccount.publicKey; }