Skip to content
Merged
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The extension adds a dedicated Ocean Protocol section to the activity bar. Here

- **Custom Docker Image/Tag**: Use your own docker image and tag (only if no Dockerfile is provided in your project folder)
- **Auth Token**: Auto-generated when you configure your compute settings
- **Custom Compute Node**: Enter your own node URL or use the default Ocean Protocol node
- **Custom Compute Node**: Enter your peer ID or use the default Ocean Protocol node
- **Compute Resources**: Free compute uses minimal resources. View available resources under the Setup dropdown
- **Paid Compute**: Upgrade from free to paid compute for more computational power
- **Node Status Check**: Use the Check button under Setup dropdown to verify node availability
Expand All @@ -78,7 +78,7 @@ The extension adds a dedicated Ocean Protocol section to the activity bar. Here
## Troubleshooting

- **Job cannot start** → Check node status (under Setup dropdown, press the Check button)
- **Job not running** → Verify your Node URL in Configure Compute
- **Job not running** → Verify your peer ID in Configure Compute
- **Not enough funds** → Use Configure Compute to adjust your settings or switch to free compute
- **General issues** → Check extension logs in the Output console. Logs are also saved in your project folder under `logs/`

Expand Down
2 changes: 1 addition & 1 deletion cheatsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Run **Compute-to-Data jobs** directly from VS Code.
## 🛠️ Troubleshooting

- ❌ Job cannot start → check node status. (Under the **Setup** dropdown, press the **Check** button)
- ❌ Job not running → check Node URL.
- ❌ Job not running → check peer ID.
- ❌ Not enough funds → use **Configure Compute** to change your compute settings.
- Always check **extension logs** in Output. Logs are also saved in your project folder under the `logs` folder.

Expand Down
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "OceanProtocol",
"displayName": "Ocean Nodes VS Code Extension",
"description": "Easily publish assets and test your algorithms with the official Ocean Protocol vscode extension.",
"version": "0.1.6",
"version": "0.1.7",
"engines": {
"vscode": "^1.96.0"
},
Expand Down Expand Up @@ -110,6 +110,7 @@
"fs": "^0.0.1-security",
"ip": "^2.0.1",
"it-pipe": "^3.0.1",
"jsonwebtoken": "^9.0.2",
"libp2p": "^2.1.5",
"node-polyfill-webpack-plugin": "^4.0.0",
"os": "^0.1.2",
Expand Down
39 changes: 39 additions & 0 deletions src/enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export enum PROTOCOL_COMMANDS {
DOWNLOAD = 'download',
DOWNLOAD_URL = 'downloadURL',
ENCRYPT = 'encrypt',
ENCRYPT_FILE = 'encryptFile',
DECRYPT_DDO = 'decryptDDO',
GET_DDO = 'getDDO',
QUERY = 'query',
NONCE = 'nonce',
STATUS = 'status',
DETAILED_STATUS = 'detailedStatus',
FIND_DDO = 'findDDO',
GET_FEES = 'getFees',
FILE_INFO = 'fileInfo',
VALIDATE_DDO = 'validateDDO',
COMPUTE_GET_ENVIRONMENTS = 'getComputeEnvironments',
COMPUTE_START = 'startCompute',
FREE_COMPUTE_START = 'freeStartCompute',
COMPUTE_STOP = 'stopCompute',
COMPUTE_GET_STATUS = 'getComputeStatus',
COMPUTE_GET_STREAMABLE_LOGS = 'getComputeStreamableLogs',
COMPUTE_GET_RESULT = 'getComputeResult',
COMPUTE_INITIALIZE = 'initializeCompute',
STOP_NODE = 'stopNode',
REINDEX_TX = 'reindexTx',
REINDEX_CHAIN = 'reindexChain',
HANDLE_INDEXING_THREAD = 'handleIndexingThread',
COLLECT_FEES = 'collectFees',
POLICY_SERVER_PASSTHROUGH = 'PolicyServerPassthrough',
GET_P2P_PEER = 'getP2PPeer',
GET_P2P_PEERS = 'getP2PPeers',
GET_P2P_NETWORK_STATS = 'getP2PNetworkStats',
FIND_PEER = 'findPeer',
CREATE_AUTH_TOKEN = 'createAuthToken',
INVALIDATE_AUTH_TOKEN = 'invalidateAuthToken',
FETCH_CONFIG = 'fetchConfig',
PUSH_CONFIG = 'pushConfig',
JOBS = 'jobs'
}
34 changes: 17 additions & 17 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
checkComputeStatus,
computeStart,
delay,
generateAuthToken,
getComputeEnvironments,
getComputeLogs,
getComputeResult,
Expand All @@ -18,7 +19,6 @@ import {
import { validateDatasetFromInput } from './helpers/validation'
import { SelectedConfig } from './types'
import { ethers, Signer } from 'ethers'
import { ProviderInstance } from '@oceanprotocol/lib'
import { checkAndReadFile, listDirectoryContents } from './helpers/path'

globalThis.fetch = fetch
Expand All @@ -31,7 +31,7 @@ vscode.window.registerUriHandler({
handleUri(uri: vscode.Uri) {
const urlParams = new URLSearchParams(uri.query)
const authToken = urlParams.get('authToken')
const nodeUrl = urlParams.get('nodeUrl')
const peerId = urlParams.get('peerId')
const isFreeCompute = urlParams.get('isFreeCompute')
const environmentId = urlParams.get('environmentId')
const feeToken = urlParams.get('feeToken')
Expand All @@ -44,7 +44,7 @@ vscode.window.registerUriHandler({
const chainIdNumber = chainId ? Number(chainId) : undefined

const resourcesParsed = resources ? SelectedConfig.parseResources(resources) : undefined
config.updateFields({ authToken, address, nodeUrl, isFreeCompute: isFreeComputeBoolean, environmentId, feeToken, jobDuration, resources: resourcesParsed, chainId: chainIdNumber })
config.updateFields({ authToken, address, peerId, isFreeCompute: isFreeComputeBoolean, environmentId, feeToken, jobDuration, resources: resourcesParsed, chainId: chainIdNumber })
console.log({ config })

// Update the UI with the new values
Expand All @@ -55,7 +55,7 @@ vscode.window.registerUriHandler({
export async function activate(context: vscode.ExtensionContext) {
let savedSigner: Signer | null = null
let savedJobId: string | null = null
let savedNodeUrl: string | null = null
let savedPeerId: string | null = null

outputChannel.show()
outputChannel.appendLine('Ocean Protocol extension is now active!')
Expand Down Expand Up @@ -96,17 +96,17 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerCommand(
'ocean-protocol.getEnvironments',
async (nodeUrl: string) => {
return await getComputeEnvironments(nodeUrl)
async (peerId: string) => {
return await getComputeEnvironments(peerId)
}
)
)

context.subscriptions.push(
vscode.commands.registerCommand(
'ocean-protocol.validateDataset',
async (nodeUrl: string, input: string) => {
return await validateDatasetFromInput(nodeUrl, input)
async (peerId: string, input: string) => {
return await validateDatasetFromInput(peerId, input)
}
)
)
Expand All @@ -120,7 +120,7 @@ export async function activate(context: vscode.ExtensionContext) {
return
}
try {
await stopComputeJob(savedNodeUrl, savedJobId, authToken || savedSigner)
await stopComputeJob(savedPeerId, savedJobId, authToken || savedSigner)
savedJobId = null
provider.sendMessage({ type: 'jobStopped' })
vscode.window.showInformationMessage('Job stopped successfully')
Expand All @@ -136,7 +136,7 @@ export async function activate(context: vscode.ExtensionContext) {
algorithmPath: string,
resultsFolderPath: string,
authToken: string | undefined,
nodeUrl: string,
peerId: string,
dataset?: string,
dockerImage?: string,
dockerTag?: string,
Expand All @@ -146,17 +146,17 @@ export async function activate(context: vscode.ExtensionContext) {
console.log('Dataset:', dataset)
console.log('Algorithm path:', algorithmPath)
console.log('Results folder path:', resultsFolderPath)
console.log('Node URL:', nodeUrl)
console.log('Peer ID:', peerId)
console.log('Auth token:', authToken)
console.log('Docker image:', dockerImage)
console.log('Docker tag:', dockerTag)
console.log('Environment ID:', environmentId)
const missingParams = []
!algorithmPath && missingParams.push('algorithm path')
!nodeUrl && missingParams.push('node URL')
!peerId && missingParams.push('peer ID')

// Save the node URL for future use
savedNodeUrl = nodeUrl
// Save the peer ID for future use
savedPeerId = peerId

if (missingParams.length > 0) {
vscode.window.showErrorMessage(
Expand All @@ -175,7 +175,7 @@ export async function activate(context: vscode.ExtensionContext) {
`Using generated wallet with address: ${signer.address}`
)
// Generate new token and register the address in the config
authToken = await ProviderInstance.generateAuthToken(signer, nodeUrl)
authToken = await generateAuthToken(peerId, signer)
config.updateFields({ address: signer.address })
} catch (error) {
console.log(error)
Expand All @@ -185,7 +185,7 @@ export async function activate(context: vscode.ExtensionContext) {
}

// Update back the config with new values from the extension
config.updateFields({ authToken, nodeUrl, environmentId })
config.updateFields({ authToken, peerId, environmentId })
provider.sendMessage({ type: 'jobLoading' })

const progressOptions = {
Expand Down Expand Up @@ -357,8 +357,8 @@ export async function activate(context: vscode.ExtensionContext) {
outputChannel.appendLine('Compute job completed successfully!')
} catch (error) {
console.log('No second result available:', error)
progress.report({ message: 'Error saving the output result' })
outputChannel.appendLine('Error saving the output result')
vscode.window.showErrorMessage('Error saving the output result')
}

break
Expand Down
46 changes: 46 additions & 0 deletions src/helpers/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ethers, JsonRpcSigner, Signer, toUtf8Bytes } from "ethers";
import jwt from 'jsonwebtoken';

const signProviderRequest = async (signer: Signer, message: string) => {
const consumerMessage = ethers.keccak256(toUtf8Bytes(message))
const messageHashBytes = ethers.getBytes(consumerMessage)
try {
return await signer.signMessage(messageHashBytes)
} catch (error) {
const network = await signer.provider.getNetwork()
const chainId = Number(network.chainId)
if (chainId === 8996) {
return await (signer as JsonRpcSigner)._legacySignMessage(messageHashBytes)
}
}
}

export const getSignature = async (
signerOrAuthToken: Signer | string,
message: string
): Promise<string | null> => {
const isAuthToken = typeof signerOrAuthToken === 'string'
return isAuthToken ? null : await signProviderRequest(signerOrAuthToken, message)
}

const decodeJwt = (token: string) => {
try {
const decoded = jwt.decode(token, { json: true })
return decoded;
} catch (error) {
throw new Error('Error decoding JWT')
}
}

export const getConsumerAddress = async (signerOrAuthToken: Signer | string): Promise<string> => {
const isAuthToken = typeof signerOrAuthToken === 'string'
return isAuthToken
? decodeJwt(signerOrAuthToken).address
: await signerOrAuthToken.getAddress()
}

export const getAuthorization = (signerOrAuthToken: Signer | string): string | undefined => {
const isAuthToken = typeof signerOrAuthToken === 'string'
return isAuthToken ? signerOrAuthToken : undefined
}

Loading