1
0
mirror of https://github.com/oceanprotocol/ocean.js.git synced 2024-11-26 20:39:05 +01:00

add download method and utils

This commit is contained in:
Bogdan Fazakas 2021-12-06 10:19:19 +02:00
parent bb828b954c
commit e9a0dd5a1c
4 changed files with 135 additions and 2 deletions

View File

@ -11,4 +11,16 @@ export interface FileMetadata {
* @type {[type]}
*/
contentLength?: string
/**
* File index.
* @type {number}
*/
index?: number
/**
* File URL.
* @type {string}
*/
url?: string
}

View File

@ -1,7 +1,10 @@
import Web3 from 'web3'
import { Config } from '../models'
import { LoggerInstance } from '../utils'
import { Asset } from '../ddo/Asset'
import { FileMetadata } from '../interfaces/FileMetadata'
import { noZeroX } from '../utils/ConversionTypeHelper'
import { signText } from '../utils/SignatureUtils'
export interface ServiceEndpoint {
serviceName: string
@ -130,7 +133,7 @@ export class Provider {
* @param {string | DID} url or did
* @param {string} providerUri Identifier of the asset to be registered in ocean
* @param {string} fetchMethod fetch client instance
* @return {Promise<File[]>} urlDetails
* @return {Promise<FileMetadata[]>} urlDetails
*/
public async fileinfo(
url: string,
@ -168,7 +171,7 @@ export class Provider {
* @param {UserCustomParameters} userCustomParameters
* @param {string} providerUri Identifier of the asset to be registered in ocean
* @param {string} fetchMethod fetch client instance
* @return {Promise<File[]>} urlDetails
* @return {Promise<FileMetadata[]>} urlDetails
*/
public async initialize(
asset: Asset,
@ -205,6 +208,69 @@ export class Provider {
}
}
public async download(
did: string,
destination: string,
accountId: string,
files: FileMetadata[],
index = -1,
providerUri: string,
web3: Web3,
fetchMethod: any,
userCustomParameters?: UserCustomParameters
): Promise<any> {
const providerEndpoints = await this.getEndpoints(providerUri, fetchMethod)
const serviceEndpoints = await this.getServiceEndpoints(
providerUri,
providerEndpoints
)
let downloadUrl = this.getEndpointURL(serviceEndpoints, 'download')
? this.getEndpointURL(serviceEndpoints, 'download').urlPath
: null
const nonce = await this.getNonce(
providerUri,
accountId,
fetchMethod,
providerEndpoints,
serviceEndpoints
)
const signature = await this.createSignature(web3, accountId, did + nonce)
if (!downloadUrl) return null
const filesPromises = files
.filter((_, i) => index === -1 || i === index)
.map(async ({ index: i, url: fileUrl }) => {
let consumeUrl = downloadUrl
consumeUrl += `?index=${i}`
consumeUrl += `&documentId=${did}`
consumeUrl += `&consumerAddress=${accountId}`
consumeUrl += `&url=${fileUrl}`
consumeUrl += `&signature=${signature}`
if (userCustomParameters)
consumeUrl += '&userdata=' + encodeURI(JSON.stringify(userCustomParameters))
try {
!destination
? await fetchMethod.downloadFileBrowser(consumeUrl)
: await fetchMethod.downloadFile(consumeUrl, destination, i)
} catch (e) {
LoggerInstance.error('Error consuming assets', e)
throw e
}
})
await Promise.all(filesPromises)
return destination
}
public async createSignature(
web3: Web3,
accountId: string,
agreementId: string
): Promise<string> {
const signature = await signText(web3, noZeroX(agreementId), accountId)
return signature
}
/** Check for a valid provider at URL
* @param {String} url provider uri address
* @param {String} fetchMethod fetch client instance

View File

@ -0,0 +1,27 @@
import { LoggerInstance } from './Logger'
export const zeroX = (input: string): string => zeroXTransformer(input, true)
export const noZeroX = (input: string): string => zeroXTransformer(input, false)
export function zeroXTransformer(input = '', zeroOutput: boolean): string {
const { valid, output } = inputMatch(input, /^(?:0x)*([a-f0-9]+)$/i, 'zeroXTransformer')
return (zeroOutput && valid ? '0x' : '') + output
}
// Shared functions
function inputMatch(
input: string,
regexp: RegExp,
conversorName: string
): { valid: boolean; output: string } {
if (typeof input !== 'string') {
LoggerInstance.debug('Not input string:')
LoggerInstance.debug(input)
throw new Error(`[${conversorName}] Expected string, input type: ${typeof input}`)
}
const match = input.match(regexp)
if (!match) {
LoggerInstance.warn(`[${conversorName}] Input transformation failed.`)
return { valid: false, output: input }
}
return { valid: true, output: match[1] }
}

View File

@ -0,0 +1,28 @@
import Web3 from 'web3'
import { LoggerInstance } from './Logger'
export async function signText(
web3: Web3,
text: string,
publicKey: string,
password?: string
): Promise<string> {
const isMetaMask =
web3 && web3.currentProvider && (web3.currentProvider as any).isMetaMask
try {
return await web3.eth.personal.sign(text, publicKey, password)
} catch (e) {
if (isMetaMask) {
throw e
}
LoggerInstance.warn('Error on personal sign.')
LoggerInstance.warn(e)
try {
return await web3.eth.sign(text, publicKey)
} catch (e2) {
LoggerInstance.error('Error on sign.')
LoggerInstance.error(e2)
throw new Error('Error executing personal sign')
}
}
}