diff --git a/dagger/contracts/market.nim b/dagger/contracts/market.nim index 770e5687..d86650da 100644 --- a/dagger/contracts/market.nim +++ b/dagger/contracts/market.nim @@ -30,6 +30,9 @@ method offerStorage(market: OnChainMarket, offer: StorageOffer) {.async.} = offer.host = await market.signer.getAddress() await market.contract.offerStorage(offer) +method selectOffer(market: OnChainMarket, offerId: array[32, byte]) {.async.} = + await market.contract.selectOffer(offerId) + method subscribeRequests(market: OnChainMarket, callback: OnRequest): Future[MarketSubscription] {.async.} = @@ -48,5 +51,15 @@ method subscribeOffers(market: OnChainMarket, let subscription = await market.contract.subscribe(StorageOffered, onEvent) return OnChainMarketSubscription(eventSubscription: subscription) +method subscribeSelection(market: OnChainMarket, + requestId: array[32, byte], + callback: OnSelect): + Future[MarketSubscription] {.async.} = + proc onSelect(event: OfferSelected) {.upraises: [].} = + if event.requestId == requestId: + callback(event.offerId) + let subscription = await market.contract.subscribe(OfferSelected, onSelect) + return OnChainMarketSubscription(eventSubscription: subscription) + method unsubscribe*(subscription: OnChainMarketSubscription) {.async.} = await subscription.eventSubscription.unsubscribe() diff --git a/dagger/contracts/storage.nim b/dagger/contracts/storage.nim index b30813f5..e101faea 100644 --- a/dagger/contracts/storage.nim +++ b/dagger/contracts/storage.nim @@ -18,6 +18,9 @@ type offerId*: Id offer*: StorageOffer requestId* {.indexed.}: Id + OfferSelected* = object of Event + offerId*: Id + requestId* {.indexed.}: Id proc collateralAmount*(storage: Storage): UInt256 {.contract, view.} proc slashMisses*(storage: Storage): UInt256 {.contract, view.} diff --git a/dagger/market.nim b/dagger/market.nim index 149fb03c..9e85ea2c 100644 --- a/dagger/market.nim +++ b/dagger/market.nim @@ -12,6 +12,7 @@ type Subscription* = ref object of RootObj OnRequest* = proc(request: StorageRequest) {.gcsafe, upraises:[].} OnOffer* = proc(offer: StorageOffer) {.gcsafe, upraises:[].} + OnSelect* = proc(offerId: array[32, byte]) {.gcsafe, upraises: [].} method requestStorage*(market: Market, request: StorageRequest) {.base, async.} = raiseAssert("not implemented") @@ -36,5 +37,11 @@ method subscribeOffers*(market: Market, Future[Subscription] {.base, async.} = raiseAssert("not implemented") +method subscribeSelection*(market: Market, + requestId: array[32, byte], + callback: OnSelect): + Future[Subscription] {.base, async.} = + raiseAssert("not implemented") + method unsubscribe*(subscription: Subscription) {.base, async.} = raiseAssert("not implemented") diff --git a/tests/contracts/testMarket.nim b/tests/contracts/testMarket.nim index 4cee3e67..a416d529 100644 --- a/tests/contracts/testMarket.nim +++ b/tests/contracts/testMarket.nim @@ -119,3 +119,47 @@ ethersuite "On-Chain Market": check submitted == @[offer] await subscription.unsubscribe() + + test "supports selection of an offer": + await token.approve(storage.address, request.maxPrice) + await market.requestStorage(request) + await market.offerStorage(offer) + + var selected: seq[array[32, byte]] + proc onSelect(offerId: array[32, byte]) = + selected.add(offerId) + let subscription = await market.subscribeSelection(request.id, onSelect) + + await market.selectOffer(offer.id) + + check selected == @[offer.id] + + await subscription.unsubscribe() + + test "subscribes only to selection for a certain request": + var otherRequest = StorageRequest.example + var otherOffer = StorageOffer.example + otherRequest.client = accounts[0] + otherOffer.host = accounts[0] + otherOffer.requestId = otherRequest.id + otherOffer.price = otherRequest.maxPrice + + await token.approve(storage.address, request.maxPrice) + await market.requestStorage(request) + await market.offerStorage(offer) + await token.approve(storage.address, otherRequest.maxPrice) + await market.requestStorage(otherRequest) + await market.offerStorage(otherOffer) + + var selected: seq[array[32, byte]] + proc onSelect(offerId: array[32, byte]) = + selected.add(offerId) + + let subscription = await market.subscribeSelection(request.id, onSelect) + + await market.selectOffer(offer.id) + await market.selectOffer(otherOffer.id) + + check selected == @[offer.id] + + await subscription.unsubscribe()