deltaDAO / nautilus

The Data Economy TypeScript Toolkit
https://nautilus.delta-dao.com
Apache License 2.0
4 stars 2 forks source link

[Feature] Provide an Example how a SaaS Service description should be done via Nautilus #70

Open BjBe82 opened 8 months ago

BjBe82 commented 8 months ago

Motivation / Problem

At the moment, it is a little bit trial and error to create a SaaS service description with nautilus. After the latest update it looks like a file type is mandatory for ServiceBuilder which is not really useful for a SaaS.

Tried:

export async function publishAnalysisStack(
  nautilus: Nautilus,
  networkConfig: NetworkConfig,
  pricingConfig: PricingConfigWithoutOwner,
  wallet: Wallet,
) {
  const owner = await wallet.getAddress();
  console.log(`The owner address is ${owner}`);

  const service = createService(networkConfig, pricingConfig);
  console.log('Created Service: ', service);

  const asset = createAsset(owner, service);
  console.log('Created Asset: ', asset);

  return nautilus.publish(asset);
}

const createService = (
  networkConfig: NetworkConfig,
  pricingConfig: PricingConfigWithoutOwner,
) => {
  const serviceBuilder = new ServiceBuilder({
    serviceType: ServiceTypes.COMPUTE,
    fileType: undefined,
  });

  return serviceBuilder
    .setServiceEndpoint(networkConfig.providerUri)
    .setTimeout(0)
    .setPricing(pricingConfig)
    .setDatatokenNameAndSymbol('COOP Analysis Stack', 'CAS')
    .setName('COOP Analysis Stack')
    .setDescription(
      'COOP Analysis Stack description. This is a placeholder for a more detailed description.',
    )
    .build();
};

const createAsset = (
  owner: string,
  service: NautilusService<ServiceTypes, FileTypes>,
) => {
  const assetBuilder = new AssetBuilder();

  return (
    assetBuilder
      .setType('algorithm')
      .setName('ScopeSET Analysis Stack')
      // supports markdown -> add some more nice text later
      .setDescription(
        `# ScopeSET Analysis Stack \n\n
        This asset has been published using [Nautilus](https://github.com/deltaDAO/nautilus).`,
      )
      .setAuthor('ScopeSET')
      .setLicense('MIT')
      .addService(service)
      .addAdditionalInformation({
        //To force the asset to be displayed as SaaS the next entry is required!
        //see https://github.com/deltaDAO/nautilus/issues/59
        saas: {
          redirectUrl: 'https://saas.helpdesk.de/',
        },
      })
      .setOwner(owner)
      .build()
  );
};

--> Error: Required attributes are missing to create a valid Ocean DDO

Using something like this:

  const serviceBuilder = new ServiceBuilder({
    serviceType: ServiceTypes.ACCESS,
    fileType: FileTypes.URL,
  });

  //we need some file as it looks like ....
  const fakeURL: UrlFile = {
    type: 'url',
    url: 'https://raw.githubusercontent.com/deltaDAO/nautilus-examples/main/example_publish_assets/example-dataset.json', // link to your file or api
    method: 'GET',
  };

  return serviceBuilder
    .setServiceEndpoint(networkConfig.providerUri)
    .setTimeout(0)
    .setPricing(pricingConfig)
    .addFile(fakeURL)
    .setDatatokenNameAndSymbol('COOP Analysis Stack', 'CAS')
    .setName('COOP Analysis Stack')
    .setDescription(
      'COOP Analysis Stack description. This is a placeholder for a more detailed description.',
    )
    .build();

works somehow.

BjBe82 commented 8 months ago

After some further testing, i was able to create a SaaS with the following config. So basically as it looks like for a SaaS using "ACCESS" a file is mandatory and if we use "COMPUTE" we need a file and an image.

For "ACCESS" i see the parameters: https://cooperants.pontus-x.eu/asset/did:op:e6a84ccb4b9423c451018cc0aeb02805c5cb1cf764d2dfa14bb1c092181aed74

For "COMPUTE" i see no parameters: https://cooperants.pontus-x.eu/asset/did:op:33d4831546875c27ca98288aa0e477d88ac4fbcd54aa0b71294f4c5b1e52338b

export async function publishAnalysisStack(
  nautilus: Nautilus,
  networkConfig: NetworkConfig,
  pricingConfig: PricingConfigWithoutOwner,
  wallet: Wallet,
) {
  const owner = await wallet.getAddress();
  console.log(`The owner address is ${owner}`);

  const service = createService(networkConfig, pricingConfig);
  console.log('Created Service: ', service);

  const asset = createAsset(owner, service);
  console.log('Created Asset: ', asset);

  return nautilus.publish(asset);
}

const createService = (
  networkConfig: NetworkConfig,
  pricingConfig: PricingConfigWithoutOwner,
) => {
  const serviceBuilder = new ServiceBuilder({
    serviceType: ServiceTypes.COMPUTE,
    fileType: FileTypes.URL,
  });

  const consumerParameterBuilder = new ConsumerParameterBuilder();

  const petitionerParam = consumerParameterBuilder
    .setType('text')
    .setName('Public Address')
    .setLabel('Public Address Label')
    .setDescription('Web3 Public Address of the petitioner.')
    .setRequired(true)
    .setDefault('0x')
    .build();

  const urlFile: UrlFile = {
    type: 'url', // there are multiple supported data source types, see https://docs.oceanprotocol.com/developers/storage
    url: 'https://raw.githubusercontent.com/deltaDAO/nautilus-examples/main/example_publish_assets/example-dataset.json', // link to your file or api
    method: 'GET', // HTTP request method
  };

  return serviceBuilder
    .setServiceEndpoint(networkConfig.providerUri)
    .setTimeout(0)
    .addFile(urlFile)
    .setPricing(pricingConfig)
    .setDatatokenNameAndSymbol('COOP Analysis Stack', 'CAS')
    .setName('COOP Analysis Stack')
    .setDescription(
      'COOP Analysis Stack description. This is a placeholder for a more detailed description.',
    )
    .addConsumerParameter(petitionerParam)
    .build();
};

const createAsset = (
  owner: string,
  service: NautilusService<ServiceTypes, FileTypes>,
) => {
  const assetBuilder = new AssetBuilder();

  const algoMetadata = {
    language: 'Node.js',
    version: '1.0.0',
    container: {
      // https://hub.docker.com/layers/library/nginx/alpine3.18-slim/images/sha256-1b0cb433e90260a96528c987ee78b797e842d510473935304a0931536d10f50d?context=explore
      entrypoint: 'NOT REQUIRED',
      image: 'nginx',
      tag: 'alpine3.18-slim',
      checksum:
        'sha256:1b0cb433e90260a96528c987ee78b797e842d510473935304a0931536d10f50d',
    },
  };

  return (
    assetBuilder
      .setType('SaaS' as any)
      .setName('ScopeSET Analysis Stack')
      // supports markdown -> add some more nice text later
      .setDescription(
        `# ScopeSET Analysis Stack \n\n
        This asset has been published using [Nautilus](https://github.com/deltaDAO/nautilus).`,
      )
      .setAuthor('ScopeSET')
      .setLicense('MIT')
      .setAlgorithm(algoMetadata)
      .addService(service)
      .addAdditionalInformation({
        //To force the asset to be displayed as SaaS the next entry is required!
        //see https://github.com/deltaDAO/nautilus/issues/59
        saas: {
          redirectUrl: 'https://saas.helpdesk.de/',
        },
      })
      .setOwner(owner)
      .build()
  );
};

I think it would be beneficial to have a minimal example how we define a SaaS via Nautilus with at least one parameter. So different parties use the same pattern to create SaaS service descriptions.

Abrom8 commented 1 month ago

We've added a SaaS example in the nautilus-examples repository.