@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
JavaScript
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;
}