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); } }; |