@zerochain/sdk
Version:
The Züs JS SDK is a JavaScript client library that provides a convenient interface for interacting with the Züs Network. It allows developers to perform various operations such as creating and managing allocations, uploading and downloading files, executi
214 lines (192 loc) • 5.84 kB
text/typescript
import { type Bridge, getBridge, globalCtx } from '../bridge'
import { getConfig } from '../loadWasm'
export const md5Hash = async (file: File): Promise<string> => {
const workerUrl = getConfig().md5WorkerUrl
if (!workerUrl) throw new Error('md5WorkerUrl is undefined')
const result = new Promise<string>((resolve, reject) => {
const worker = new Worker(workerUrl)
worker.postMessage(file)
worker.onmessage = e => {
resolve(e.data)
worker.terminate()
}
worker.onerror = reject
})
return result
}
export const readChunk = (
offset: number,
chunkSize: number,
file: File
): Promise<{ size: number; buffer: Uint8Array }> =>
new Promise<{ size: number; buffer: Uint8Array }>((res, rej) => {
const fileReader = new FileReader()
const blob = file.slice(offset, chunkSize + offset)
fileReader.onload = e => {
const t = e.target
if (t === null) {
rej('err: fileReader onload target is null')
return
}
if (t.error == null) {
const result = t.result as ArrayBuffer
res({
size: result.byteLength,
buffer: new Uint8Array(result),
})
} else {
rej(t.error)
}
}
fileReader.readAsArrayBuffer(blob)
})
// TODO: returns the proxy `GoWasmProxy`
const getProxy = (bridge: Bridge) => {
const proxy = bridge.__proxy__
if (!proxy) {
throw new Error(
'The Bridge proxy (__proxy__) is not initialized. Make sure to call createWasm first.'
)
}
return proxy
}
export type UploadObject = {
allocationId: string
remotePath: string
file: File
thumbnailBytes: Uint8Array
encrypt: boolean
isUpdate: boolean
isRepair: boolean
numBlocks: number
callback: (totalBytes: number, completedBytes: number, error: any) => void
/** @deprecated */
webstreaming: boolean
}
/**
* Performs a bulk upload of multiple files.
*
* @param options An array of upload options for each file.
*
* @deprecated use `multiUplaod` methods instead
*/
export async function bulkUpload(options: UploadObject[]): Promise<any> {
const g = globalCtx()
const bridge = getBridge()
const start = bridge.glob.index
const opts = options.map(obj => {
const i = bridge.glob.index
bridge.glob.index++
const readChunkFuncName = '__zcn_upload_reader_' + i.toString()
const callbackFuncName = '__zcn_upload_callback_' + i.toString()
let md5HashFuncName = ''
g[readChunkFuncName] = async (offset: number, chunkSize: number) => {
console.log(
'bulk_upload: read chunk remotePath:' +
obj.remotePath +
' offset:' +
offset +
' chunkSize:' +
chunkSize
)
const chunk = await readChunk(offset, chunkSize, obj.file)
return chunk.buffer
}
if (obj.file.size > 25 * 1024 * 1024) {
md5HashFuncName = '__zcn_md5_hash_' + i.toString()
const md5Res = md5Hash(obj.file)
g[md5HashFuncName] = async () => {
const hash = await md5Res
return hash
}
}
if (obj.callback) {
g[callbackFuncName] = async (
totalBytes: number,
completedBytes: number,
error: any
) => obj.callback(totalBytes, completedBytes, error)
}
return {
allocationId: obj.allocationId,
remotePath: obj.remotePath,
fileSize: obj.file.size,
encrypt: obj.encrypt,
isUpdate: obj.isUpdate,
isRepair: obj.isRepair,
numBlocks: obj.numBlocks,
webstreaming: obj.webstreaming,
thumbnailBytes: Array.from(obj?.thumbnailBytes || []).toString(),
readChunkFuncName: readChunkFuncName,
callbackFuncName: callbackFuncName,
md5HashFuncName: md5HashFuncName,
}
})
const end = bridge.glob.index
const proxy = getProxy(bridge)
const result = await proxy.sdk.bulkUpload(JSON.stringify(opts))
for (let i = start; i < end; i++) {
g['__zcn_upload_reader_' + i.toString()] = null
g['__zcn_upload_callback_' + i.toString()] = null
}
return result
}
/**
* Sets the wallet information in the bridge and the Go instance.
*
* @param bls The BLS object from bls-wasm script.
* @param clientID The client ID / wallet ID.
* @param clientKey The client key.
* @param peerPublicKey The peer public key.
* @param sk The serialized secret key.
* @param pk The serialized public key.
* @param mnemonic The mnemonic.
* @param isSplit Whether the wallet has split keys enabled or not.
*/
export async function setWallet(
bls: any, // TODO: check bls
clientID: string,
clientKey: string,
peerPublicKey: string,
sk: string,
pk: string,
mnemonic: string,
isSplit: boolean
): Promise<void> {
if (!bls) throw new Error('bls is undefined')
if (!sk) throw new Error('secret key is undefined')
if (!pk) throw new Error('public key is undefined')
if (isSplit && !clientKey) throw new Error('clientKey is undefined')
const bridge = getBridge()
if (
bridge.walletId != clientID ||
bridge.jsProxy.pubkeyStr != pk ||
bridge.jsProxy.isSplit != isSplit
) {
bridge.jsProxy.bls = bls
bridge.jsProxy.secretKey = bls.deserializeHexStrToSecretKey(sk)
bridge.jsProxy.publicKey = bls.deserializeHexStrToPublicKey(pk)
bridge.jsProxy.pubkeyStr = pk
bridge.jsProxy.isSplit = isSplit
const proxy = getProxy(bridge)
if (!proxy?.sdk?.setWallet)
throw new Error('proxy.sdk.setWallet is not defined')
await proxy.sdk.setWallet(
clientID,
clientKey,
peerPublicKey,
pk,
sk,
mnemonic,
isSplit
)
bridge.walletId = clientID
bridge.secretKey = sk
bridge.peerPublicKey = peerPublicKey
}
}
export type SdkProxyMethods = {
/** @deprecated use `multiUplaod` methods instead */
bulkUpload: typeof bulkUpload
setWallet: typeof setWallet
}