import fetch from 'cross-fetch' ; import * as u8a from 'uint8arrays' ; import { LRUMap } from 'lru_map' ; interface DAG { get ( cid ) : any ; } interface IPFS { dag : DAG ; } const THREEBOX_API_URL = 'https://ipfs.3box.io' ; const LIMIT = 100 ; const fetchCache = new LRUMap < string , any > ( LIMIT ) ; const fetchJson = async ( url ) : Promise < any > => { const cached = fetchCache . get ( url ) ; if ( cached ) return cached ; const r = await fetch ( url ) ; if ( r . ok ) { const json = await r . json ( ) ; fetchCache . set ( url , json ) ; return json ; } else { throw new Error ( 'Not a valid 3ID' ) ; } } ; const didDocReq = ( cid ) : string => `${ THREEBOX_API_URL }/did-doc?cid=${ encodeURIComponent ( cid ) }` ; const ipfsMock = { dag : { get : async ( cid ) => fetchJson ( didDocReq ( cid ) ) , } , } ; const encodeKey = ( key , encryption ? ) : string => { const bytes = new Uint8Array ( key . length + 2 ) ; if ( encryption ) { bytes [ 0 ] = 0xec ; } else { bytes [ 0 ] = 0xe7 ; } bytes [ 1 ] = 0x01 ; bytes . set ( key , 2 ) ; return `z${ u8a . toString ( bytes , 'base58btc' ) }` ; } ; const compressKey = ( key ) => { const xpoint = key . slice ( 2 , 66 ) ; const ypoint = key . slice ( 66 , 130 ) ; const prefix = ( ypoint & 1 ) === 0 ? '02' : '03' ; return `${ prefix }${ xpoint }` ; } ; const LegacyResolver = async ( didId , ipfs = ipfsMock ) : Promise < any > => { const doc = ( await ipfs . dag . get ( didId ) ) . value ; let signingKey , encryptionKey ; try { const keyEntrySigning = doc . publicKey . findIndex ( ( e ) => e . id . endsWith ( 'signingKey' ) ) ; const keyEntryEncryption = doc . publicKey . findIndex ( ( e ) => e . id . endsWith ( 'encryptionKey' ) ) ; signingKey = doc . publicKey [ keyEntrySigning ] . publicKeyHex ; encryptionKey = doc . publicKey [ keyEntryEncryption ] . publicKeyBase64 ; } catch ( e ) { throw new Error ( 'Not a valid 3ID' ) ; } const signingKeyCompressed = compressKey ( signingKey ) ; const signing = encodeKey ( u8a . fromString ( signingKeyCompressed , 'base16' ) ) ; const encryption = encodeKey ( u8a . fromString ( encryptionKey , 'base64pad' ) , true ) ; return { keyDid : `did:key:${ signing }` , publicKeys : { [ signing . slice ( - 15 ) ] : signing , [ encryption . slice ( - 15 ) ] : encryption , } , } ; } ; export default LegacyResolver ;