Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selecting flow based on service #377

Closed
wants to merge 3 commits into from
Closed
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
12 changes: 11 additions & 1 deletion src/ddo/Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,17 @@ export interface ValidationParams {
nft_holder?: string
}

export interface AccessSelector {
isDTP: boolean
ercType?: ERCType
}

export interface ServicePlugin {
createService(publisher: Account, metadata: MetaData): Promise<ServiceCommon>
createService(
publisher: Account,
metadata: MetaData,
access: AccessSelector
): Promise<ServiceCommon>
// Process agreement for provider
process(
params: ValidationParams,
Expand All @@ -208,4 +217,5 @@ export interface ServicePlugin {
): Promise<void>
// Check if service can be granted without agreement
accept(params: ValidationParams): Promise<boolean>
service(): ServiceType
}
6 changes: 2 additions & 4 deletions src/keeper/contracts/conditions/EscrowPaymentCondition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ConditionInstanceSmall,
ProviderCondition
} from './Condition.abstract'
import { didZeroX, findServiceConditionByName, zeroX } from '../../../utils'
import { didZeroX, findConditionParameter, zeroX } from '../../../utils'
import { InstantiableConfig } from '../../../Instantiable.abstract'
import Account from '../../../nevermined/Account'
import { TxParameters } from '../ContractBase'
Expand Down Expand Up @@ -51,15 +51,13 @@ export class EscrowPaymentCondition extends ProviderCondition<EscrowPaymentCondi
access: ConditionInstanceSmall,
lock: ConditionInstanceSmall
) {
const escrow = findServiceConditionByName(service, 'escrowPayment')
if (!escrow) throw new Error('Escrow Condition not found!')
return this.params(
ddo.shortId(),
rewards.getAmounts(),
rewards.getReceivers(),
consumerId,
this.nevermined.keeper.conditions.escrowPaymentCondition.getAddress(),
escrow.parameters.find(p => p.name === '_tokenAddress').value as string,
findConditionParameter(service, 'escrowPayment', '_tokenAddress') as string,
lock.id,
access.id
)
Expand Down
5 changes: 2 additions & 3 deletions src/keeper/contracts/conditions/LockPaymentCondition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Condition, ConditionContext, ConsumerCondition } from './Condition.abstract'
import { didZeroX, findServiceConditionByName, zeroX } from '../../../utils'
import { didZeroX, findConditionParameter, zeroX } from '../../../utils'
import { InstantiableConfig } from '../../../Instantiable.abstract'
import Account from '../../../nevermined/Account'
import { TxParameters } from '../ContractBase'
Expand Down Expand Up @@ -31,11 +31,10 @@ export class LockPaymentCondition extends ConsumerCondition<ConditionContext> {
}

public async paramsFromDDO({ ddo, service, rewards }: ConditionContext) {
const payment = findServiceConditionByName(service, 'lockPayment')
return this.params(
ddo.shortId(),
this.nevermined.keeper.conditions.escrowPaymentCondition.getAddress(),
payment.parameters.find(p => p.name === '_tokenAddress').value as string,
findConditionParameter(service, 'lockPayment', '_tokenAddress') as string,
rewards.getAmounts(),
rewards.getReceivers()
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InstantiableConfig } from '../../../../Instantiable.abstract'
import { didZeroX, findServiceConditionByName, zeroX } from '../../../../utils'
import { didZeroX, findConditionParameter, zeroX } from '../../../../utils'
import { Condition, ConditionContext, ConsumerCondition } from '../Condition.abstract'
import Account from '../../../../nevermined/Account'
import { TxParameters } from '../../ContractBase'
Expand Down Expand Up @@ -42,9 +42,7 @@ export class NFT721HolderCondition extends ConsumerCondition<NFT721HolderConditi
}

public nftContractFromService(service: ServiceCommon): string {
const holder = findServiceConditionByName(service, 'nftHolder')
if (!holder) throw new Error('Holder condition not found!')
return holder.parameters.find(p => p.name === '_contractAddress').value as string
return findConditionParameter(service, 'nftHolder', '_contractAddress')
}

public async paramsFromDDO({
Expand Down
6 changes: 2 additions & 4 deletions src/keeper/contracts/conditions/NFTs/NFTHolderCondition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InstantiableConfig } from '../../../../Instantiable.abstract'
import { didZeroX, findServiceConditionByName, zeroX } from '../../../../utils'
import { didZeroX, findConditionParameter, zeroX } from '../../../../utils'
import { Condition, ConditionContext, ConsumerCondition } from '../Condition.abstract'
import Account from '../../../../nevermined/Account'
import { TxParameters } from '../../ContractBase'
Expand Down Expand Up @@ -34,9 +34,7 @@ export class NFTHolderCondition extends ConsumerCondition<NFTHolderConditionCont
}

public amountFromService(service: ServiceCommon): BigNumber {
const holder = findServiceConditionByName(service, 'nftHolder')
if (!holder) throw new Error('Holder condition not found!')
return BigNumber.from(holder.parameters.find(p => p.name === '_numberNfts').value)
return BigNumber.from(findConditionParameter(service, 'nftHolder', '_numberNfts'))
}

public async paramsFromDDO({
Expand Down
18 changes: 8 additions & 10 deletions src/keeper/contracts/conditions/NFTs/TransferNFT721Condition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InstantiableConfig } from '../../../../Instantiable.abstract'
import { didZeroX, findServiceConditionByName, zeroX } from '../../../../utils'
import { didZeroX, findConditionParameter, zeroX } from '../../../../utils'
import {
Condition,
ConditionContext,
Expand Down Expand Up @@ -89,20 +89,18 @@ export class TransferNFT721Condition extends ProviderCondition<TransferNFT721Con
{ ddo, service, consumerId, expiration }: TransferNFT721ConditionContext,
lockCondition
) {
const transfer = findServiceConditionByName(service, 'transferNFT')
if (!transfer) throw new Error('TransferNFT condition not found!')

const nft = await this.nevermined.contracts.loadNft721(
transfer.parameters.find(p => p.name === '_contractAddress').value as string
findConditionParameter(service, 'transferNFT', '_contractAddress') as string
)
const nftHolder = transfer.parameters.find(p => p.name === '_nftHolder')
.value as string

const nftTransferString = transfer.parameters.find(p => p.name === '_nftTransfer')
.value as string
const nftTransferString = findConditionParameter(
service,
'transferNFT',
'_nftTransfer'
) as string
return this.params(
ddo.shortId(),
nftHolder,
findConditionParameter(service, 'transferNFT', '_nftHolder') as string,
consumerId,
lockCondition.id,
nft.address,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InstantiableConfig } from '../../../../Instantiable.abstract'
import { didZeroX, findServiceConditionByName, zeroX } from '../../../../utils'
import { didZeroX, findConditionParameter, zeroX } from '../../../../utils'
import {
Condition,
ConditionContext,
Expand Down Expand Up @@ -91,11 +91,8 @@ export class TransferNFTCondition extends ProviderCondition<TransferNFTCondition
{ ddo, service, providerId, consumerId, nftAmount }: TransferNFTConditionContext,
lockCondition
) {
const transfer = findServiceConditionByName(service, 'transferNFT')
if (!transfer) throw new Error('TransferNFT condition not found!')
const nftHolder =
providerId ||
(transfer.parameters.find(p => p.name === '_nftHolder').value as string)
providerId || findConditionParameter(service, 'transferNFT', '_nftHolder')
return this.params(
ddo.shortId(),
nftHolder,
Expand Down
20 changes: 11 additions & 9 deletions src/keeper/contracts/templates/AgreementTemplate.abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { DDO } from '../../../ddo/DDO'
import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
import {
didZeroX,
findServiceConditionByName,
findConditionParameter,
getAssetRewardsFromService,
OrderProgressStep,
ZeroAddress,
Expand Down Expand Up @@ -84,13 +84,14 @@ export abstract class AgreementTemplate<Params> extends ContractBase {

public paymentData(service: Service): PaymentData {
const assetRewards = getAssetRewardsFromService(service)
const payment = findServiceConditionByName(service, 'lockPayment')
if (!payment) throw new Error('Payment Condition not found!')
return {
rewardAddress:
this.nevermined.keeper.conditions.escrowPaymentCondition.getAddress(),
tokenAddress: payment.parameters.find(p => p.name === '_tokenAddress')
.value as string,
tokenAddress: findConditionParameter(
service,
'lockPayment',
'_tokenAddress'
) as string,
amounts: assetRewards.getAmounts(),
receivers: assetRewards.getReceivers()
}
Expand Down Expand Up @@ -274,12 +275,13 @@ export abstract class AgreementTemplate<Params> extends ContractBase {

const service = ddo.findServiceByType(this.service())
const assetRewards = getAssetRewardsFromService(service)
const payment = findServiceConditionByName(service, 'lockPayment')
if (!payment) throw new Error('Payment Condition not found!')
const rewardAddress =
this.nevermined.keeper.conditions.escrowPaymentCondition.getAddress()
const tokenAddress = payment.parameters.find(p => p.name === '_tokenAddress')
.value as string
const tokenAddress = findConditionParameter<string>(
service,
'lockPayment',
'_tokenAddress'
)
const amounts = assetRewards.getAmounts()
const receivers = assetRewards.getReceivers()

Expand Down
40 changes: 22 additions & 18 deletions src/nevermined/AccessService.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ServiceCommon, ServicePlugin, ValidationParams } from '../ddo/Service'
import {
AccessSelector,
ServiceCommon,
ServicePlugin,
ServiceType,
ValidationParams
} from '../ddo/Service'
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
import { TxParameters } from '../keeper/contracts/ContractBase'
import { Account, MetaData, MetaDataMain } from '../sdk'

export interface AccessProofTemplateParams {
type: 'access-proof'
consumer: Account
consumerId: string
}
import { Account, MetaData } from '../sdk'

export class AccessService extends Instantiable implements ServicePlugin {
normal: ServicePlugin
Expand All @@ -20,30 +20,34 @@ export class AccessService extends Instantiable implements ServicePlugin {
}

// essential method is to select between two services
public select(main: MetaDataMain): ServicePlugin {
return main.isDTP ? this.proof : this.normal
public select(selector: AccessSelector): ServicePlugin {
return selector.isDTP ? this.proof : this.normal
}

public async createService(
publisher: Account,
metadata: MetaData
metadata: MetaData,
selector: AccessSelector
): Promise<ServiceCommon> {
return this.select(metadata.main).createService(publisher, metadata)
return this.select(selector).createService(publisher, metadata, selector)
}
public async process(
params: ValidationParams,
from: Account,
txparams?: TxParameters
): Promise<void> {
const ddo = await this.nevermined.assets.resolve(params.did)
const metadata = ddo.findServiceByType('metadata').attributes.main
const metadata = ddo.findServiceByType(this.service()).attributes.main
return this.select(metadata).process(params, from, txparams)
}
public async accept(params: ValidationParams): Promise<boolean> {
const ddo = await this.nevermined.assets.resolve(params.did)
const metadata = ddo.findServiceByType('metadata').attributes.main
const metadata = ddo.findServiceByType(this.service()).attributes.main
return this.select(metadata).accept(params)
}
public service(): ServiceType {
return this.normal.service()
}
}

export class NFTAccessService extends AccessService implements ServicePlugin {
Expand All @@ -60,11 +64,11 @@ export class NFTAccessService extends AccessService implements ServicePlugin {
}

// essential method is to select between two services
public select(main: MetaDataMain): ServicePlugin {
if (main.ercType == 1155) {
return main.isDTP ? this.proof : this.normal
public select(selector: AccessSelector): ServicePlugin {
if (selector.ercType == 1155) {
return selector.isDTP ? this.proof : this.normal
} else {
return main.isDTP ? this.proof721 : this.normal721
return selector.isDTP ? this.proof721 : this.normal721
}
}
}
6 changes: 2 additions & 4 deletions src/nevermined/AgreementsConditions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Account from './Account'
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
import { DDO } from '../ddo/DDO'
import { findServiceConditionByName, ZeroAddress } from '../utils'
import { findConditionParameter, ZeroAddress } from '../utils'
import Token from '../keeper/contracts/Token'
import CustomToken from '../keeper/contracts/CustomToken'
import { TxParameters } from '../keeper/contracts/ContractBase'
Expand Down Expand Up @@ -364,13 +364,11 @@ export class AgreementsConditions extends Instantiable {
const { nft721HolderCondition } = this.nevermined.keeper.conditions
const accessService = ddo.findServiceByType('nft-access')

const holder = findServiceConditionByName(accessService, 'nftHolder')

const contractReceipt: ContractReceipt = await nft721HolderCondition.fulfill(
agreementId,
ddo.shortId(),
holderAddress,
holder.parameters.find(p => p.name === '_contractAddress').value as string,
findConditionParameter(accessService, 'nftHolder', '_contractAddress'),
from,
params
)
Expand Down
2 changes: 1 addition & 1 deletion src/nevermined/Assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class Assets extends Instantiable {
if (plugin) {
await ddo.addService(
this.nevermined,
await plugin.createService(publisher, metadata)
await plugin.createService(publisher, metadata, metadata.main)
)
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/nevermined/Nfts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import AssetRewards from '../models/AssetRewards'
import { DDO, utils } from '../sdk'
import {
fillConditionsWithDDO,
findServiceConditionByName,
generateId,
getAssetRewardsFromService,
getDIDFromService,
Expand All @@ -13,7 +12,8 @@ import {
OrderProgressStep,
noZeroX,
SubscribablePromise,
zeroX
zeroX,
findConditionParameter
} from '../utils'
import { CreateProgressStep, RoyaltyAttributes, RoyaltyKind } from './Assets'
import Account from './Account'
Expand Down Expand Up @@ -943,14 +943,12 @@ export class Nfts extends Instantiable {

if (!agreementId) throw new Error('Creating buy agreement failed')

const payment = findServiceConditionByName(service, 'lockPayment')

const receipt = await this.nevermined.agreements.conditions.lockPayment(
agreementId,
ddo.id,
assetRewards.getAmounts(),
assetRewards.getReceivers(),
payment.parameters.find(p => p.name === '_tokenAddress').value as string,
findConditionParameter(service, 'lockPayment', '_tokenAddress'),
consumer,
params
)
Expand Down
18 changes: 18 additions & 0 deletions src/utils/DDOHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,21 @@ export function getNftAmountFromService(service: Service): BigNumber {
nftTransferCondition.parameters.find(p => p.name === '_numberNfts').value
)
}

export function findConditionParameter<T>(
service: Service,
condName: ConditionType,
paramName: string
): T {
const cond = findServiceConditionByName(service, condName)
if (!cond) {
throw new Error(`Unknown condition ${condName} in ${service.type}`)
}
const param = cond.parameters.find(p => p.name === paramName)
if (!param) {
throw new Error(
`Missing parameter ${paramName} in condition ${condName} of ${service.type}`
)
}
return param.value as T
}