Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
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