Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"./packages/icons/**",
"./packages/mask/swap/webgl/**",
"./packages/web3-contracts/types/**",
"./patches/**",
".github",
".gitignore",
".patch",
Expand Down Expand Up @@ -66,6 +67,7 @@
"cyberconnect",
"cyberlab",
"darkweb",
"dataitem",
"debank",
"deficonnect",
"devnet",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"yarn": ">=999.0.0",
"npm": ">=999.0.0"
},
"version": "2.34.0",
"version": "2.34.1",
"private": true,
"license": "AGPL-3.0-or-later",
"scripts": {
Expand Down
5 changes: 4 additions & 1 deletion packages/mask/.webpack/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ export async function createConfiguration(
console.error("Environment variable WEB3_CONSTANTS_RPC should be JSON.stringify'ed twice")
WEB3_CONSTANTS_RPC = JSON.stringify(WEB3_CONSTANTS_RPC)
}
} catch (err) {}
} catch (err) {
console.error('Environment variable WEB3_CONSTANTS_RPC is not valid JSON')
}
}
const baseConfig = {
name: 'mask',
Expand Down Expand Up @@ -239,6 +241,7 @@ export async function createConfiguration(
SOLANA_DEFAULT_RPC_URL: process.env.SOLANA_DEFAULT_RPC_URL || '',
MASK_ENABLE_EXCHANGE: process.env.MASK_ENABLE_EXCHANGE || '',
GOOGLE_CLIENT_ID: JSON.stringify(process.env.GOOGLE_CLIENT_ID) || '',
LOAD_KEY: process.env.LOAD_KEY || '',
}),
new (rspack?.DefinePlugin || webpack.default.DefinePlugin)({
'process.browser': 'true',
Expand Down
66 changes: 29 additions & 37 deletions packages/plugins/FileService/src/Worker/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import { Attachment } from '@dimensiondev/common-protocols'
import { encodeText } from '@masknet/kit'
import { LANDING_PAGE, Provider } from '../constants.js'
import type { ProviderAgent, LandingPageMetadata, AttachmentOptions } from '../types.js'
import { makeFileKeySigned } from '../helpers.js'
import { LOAD_LEGACY_GATEWAY_URL, LOAD_LEGACY_ID_REGEX, makeFileKeySigned } from '../helpers.js'

const LOAD_GATEWAY_URL = 'https://load0.network/resolve'
const LOAD_UPLOAD_ENDPOINT = 'https://load0.network/upload'
const API_KEY = 'load_acc_ep4bep0uGlmUXMu46BxM0uWXKsqL5M5w' // move to env
const LOAD_GATEWAY_URL = 'https://load-s3-agent.load.network'
const LOAD_UPLOAD_ENDPOINT = 'https://load-s3-agent.load.network/upload'

class LoadAgent implements ProviderAgent {
static providerName = 'Load Network'
Expand Down Expand Up @@ -51,7 +50,9 @@ class LoadAgent implements ProviderAgent {

async uploadLandingPage(metadata: LandingPageMetadata) {
this.init()
const linkPrefix = LOAD_GATEWAY_URL
// decide which gateway URL to use based on ID
const linkPrefix = LOAD_LEGACY_ID_REGEX.test(metadata.txId) ? LOAD_LEGACY_GATEWAY_URL : LOAD_GATEWAY_URL

const encodedMetadata = JSON.stringify({
name: metadata.name,
size: metadata.size,
Expand All @@ -60,6 +61,7 @@ class LoadAgent implements ProviderAgent {
signed: await makeFileKeySigned(metadata.key),
createdAt: new Date().toISOString(),
})

const response = await fetch(LANDING_PAGE)
const text = await response.text()
const replaced = text
Expand All @@ -68,48 +70,38 @@ class LoadAgent implements ProviderAgent {
.replace('__METADATA__', encodedMetadata)

const data = encodeText(replaced)

const landingPageTxId = await this.makePayload(data, 'text/html', `${metadata.name}-landing.html`)

return landingPageTxId
}

async makePayload(data: Uint8Array, type: string, fileName: string = 'file.dat') {
this.init()

try {
const blob = new Blob([data], { type })
const headers = {
'Content-Type': type,
Filename: fileName,
'App-Name': 'Maskbook',
'X-Load-Authorization': API_KEY,
}

const response = await fetch(LOAD_UPLOAD_ENDPOINT, {
method: 'POST',
headers,
body: blob,
signal: this.uploadController?.signal,
})

if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`)
}

const { optimistic_hash } = await response.json()
return optimistic_hash
} catch (error) {
const errorMessage = `Load Network upload failed: ${error instanceof Error ? error.message : String(error)}`
console.error('Load Network detailed error:', errorMessage)
const blob = new Blob([data], { type })
const formData = new FormData()
formData.append('file', blob)
formData.append('content_type', type)
formData.append('app_name', 'Maskbook')

const response = await fetch(LOAD_UPLOAD_ENDPOINT, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LOAD_KEY}`,
},
body: formData,
signal: this.uploadController?.signal,
})

const enhancedError = new Error(errorMessage)
if (error instanceof Error && error.stack) {
enhancedError.stack = error.stack
}
if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`)
}

throw enhancedError
const result = await response.json()
if (!result.success || !result.dataitem_id) {
throw new Error('Invalid response from upload service')
}

return result.dataitem_id
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/FileService/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export const META_KEY_2 = 'com.maskbook.fileservice:2'
export const META_KEY_3 = 'com.maskbook.fileservice:3'

export const MAX_FILE_SIZE = 10 * 1000 * 1000
export const MAX_FILE_SIZE_LOAD = 10 * 1024 * 1024
export const MAX_FILE_SIZE_LOAD = 30 * 1024 * 1024

export const LANDING_PAGE = 'https://files.r2d2.to/partner/arweave/landing-page.html'
export const RECOVERY_PAGE = 'https://fileservice.r2d2.to/recover'
Expand Down
13 changes: 11 additions & 2 deletions packages/plugins/FileService/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import schemaV1 from './schema-v1.json' with { type: 'json' }
import schemaV2 from './schema-v2.json' with { type: 'json' }
import schemaV3 from './schema-v3.json' with { type: 'json' }

// Load legacy detection + gateway
export const LOAD_LEGACY_ID_REGEX = /^0x[a-f0-9]{64}$/iu
export const LOAD_LEGACY_GATEWAY_URL = 'https://load0.network/download'

// Note: if the latest version has been changed, please update packages/mask/content-script/components/CompositionDialog/useSubmit.ts
const reader_v1 = createTypedMessageMetadataReader<FileInfoV1>(META_KEY_1, schemaV1)
const reader_v2 = createTypedMessageMetadataReader<FileInfo>(META_KEY_2, schemaV2)
Expand Down Expand Up @@ -45,7 +49,7 @@ const resolveGatewayAPI = createLookupTableResolver<Provider, string>(
{
[Provider.Arweave]: 'https://arweave.net',
[Provider.IPFS]: 'https://mask.infura-ipfs.io/ipfs',
[Provider.Load]: 'https://load0.network/resolve',
[Provider.Load]: 'https://load-s3-agent.load.network',
},
() => 'Unknown provider',
)
Expand All @@ -61,7 +65,12 @@ export function makeFileKey(length = 16) {
}

export function downloadFile(file: FileInfo) {
const gateway = resolveGatewayAPI(file.provider)
let gateway = resolveGatewayAPI(file.provider)

if (file.provider === Provider.Load && LOAD_LEGACY_ID_REGEX.test(String(file.landingTxID ?? ''))) {
gateway = LOAD_LEGACY_GATEWAY_URL
}

let link = urlcat(gateway, '/:txId', { txId: file.landingTxID })
if (isAfter(new Date(2022, 8, 1), new Date(file.createdAt))) {
link = urlcat(RECOVERY_PAGE, {
Expand Down