Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 4x 4x 4x 4x 4x 4x 4x 15x 9x 4x 6x 4x 4x 4x 4x 4x 1x 1x 1x 1x 1x 4x | import {
ClarityValue,
cvToHex,
hexToCV,
serializeCV,
stringAsciiCV,
tupleCV,
uintCV,
} from 'micro-stacks/clarity';
import { ChainID, cleanHex, concatByteArrays } from 'micro-stacks/common';
import { Json } from 'micro-stacks/crypto';
import { openSignStructuredDataPopup } from '../popup';
import type { SignedOptionsWithOnHandlers, StructuredSignatureRequestOptions } from './types';
import { sha256 } from '@noble/hashes/sha256';
import { safeGetPublicKey } from '../common/utils';
import { createWalletJWT } from '../common/create-wallet-jwt';
const structuredDataPrefix = Uint8Array.from([0x53, 0x49, 0x50, 0x30, 0x31, 0x38]); // SIP018
export const makeClarityHash = (clarityValue: ClarityValue) => sha256(serializeCV(clarityValue));
export const makeDomainTuple = (name: string, version: string, chainId: ChainID) =>
tupleCV({
name: stringAsciiCV(name),
version: stringAsciiCV(version),
'chain-id': uintCV(chainId),
});
export const makeStructuredDataHash = (
domainHash: Uint8Array,
structuredMessageHash: Uint8Array
) => {
return sha256(concatByteArrays([structuredDataPrefix, domainHash, structuredMessageHash]));
};
export const getStructuredDataHashes = (options: {
message: StructuredSignatureRequestOptions['message'];
domain: StructuredSignatureRequestOptions['domain'];
}) => {
const message: ClarityValue =
typeof options.message === 'string' ? hexToCV(options.message) : options.message;
const domain = makeDomainTuple(
options.domain.name,
options.domain.version,
options.domain.chainId ?? ChainID.Mainnet
);
return {
message: makeClarityHash(message),
domain: makeClarityHash(domain),
};
};
export const generateSignStructuredDataPayload = async (
options: StructuredSignatureRequestOptions
) => {
const message: string =
typeof options.message !== 'string' ? cvToHex(options.message) : options.message;
const domainTuple = makeDomainTuple(
options.domain.name,
options.domain.version,
options.domain.chainId ?? options.network?.chainId ?? ChainID.Mainnet
);
const domain: string = cvToHex(domainTuple);
const payload: Json = {
stxAddress: options.stxAddress,
message: cleanHex(message),
domain: cleanHex(domain),
appDetails: options.appDetails,
publicKey: safeGetPublicKey(options.privateKey),
network: options.network as any,
};
return createWalletJWT(payload, options?.privateKey);
};
export const handleSignStructuredDataRequest = async (
options: SignedOptionsWithOnHandlers<StructuredSignatureRequestOptions>
) => {
try {
const token = await generateSignStructuredDataPayload({
message: options.message,
domain: options.domain,
privateKey: options.privateKey,
stxAddress: options.stxAddress,
authOrigin: options.authOrigin,
appDetails: options.appDetails,
network: options.network,
});
return openSignStructuredDataPopup({
token,
onFinish: options.onFinish,
onCancel: options.onCancel,
});
} catch (e: unknown) {
console.error(`[micro-stacks] handleSignStructuredDataRequest failed`);
console.error(e);
}
};
|