import { FetchResultCode , ICasService , FetchResult , ServiceVersionModel , } from '@sidetree/common' ; import Unixfs from 'ipfs-unixfs' ; import { DAGNode } from 'ipld-dag-pb' ; import S3 from 'aws-sdk/clients/s3' ; import { CredentialsOptions } from 'aws-sdk/lib/credentials' ; const { version } = require ( '../package.json' ) ; /**
 * Implementation of a CAS class for testing.
 * Simply using a hash map to store all the content by hash.
 */ export default class S3Cas implements ICasService { private s3 : S3 ; constructor ( private bucketName , config ? ) { if ( ! this . bucketName ) { throw new Error ( 'You must specify a bucketName' ) ; } if ( config ) { this . s3 = new S3 ( { ... config } ) ; } else { this . s3 = new S3 ( ) ; } } public getServiceVersion : ( ) => Promise < ServiceVersionModel > = ( ) => { return Promise . resolve ( { name : 'cas-s3' , version } ) ; } ; async initialize ( ) { if ( this . s3 . config . credentials ) { const bucketParams = { Bucket : this . bucketName } ; await this . s3 . createBucket ( bucketParams ) . promise ( ) ; } } async close ( ) { return ; } /**
     * Gets the address that can be used to access the given content.
     */ public static async getAddress ( content ) { const unixFs = new Unixfs ( 'file' , content ) ; const marshaled = unixFs . marshal ( ) ; const dagNode = new DAGNode ( marshaled ) ; const dagLink = await dagNode . toDAGLink ( { cidVersion : 0 } ) ; return dagLink . Hash . toString ( ) ; } public async write ( content ) { const encodedHash = await S3Cas . getAddress ( content ) ; const writeResult = await this . s3 . upload ( { Bucket : this . bucketName , Key : encodedHash , Body : content } ) . promise ( ) ; const key = writeResult . Key ; console . assert ( key === encodedHash , `${ key } should match ${ encodedHash }` ) ; return key ; } public async read ( address ) { try { const readResult = await this . s3 . getObject ( { Bucket : this . bucketName , Key : address } ) . promise ( ) ; const content = readResult . Body as Buffer ; return { code : FetchResultCode . Success , content } ; } catch ( err ) { return { code : FetchResultCode . NotFound } ; } } }