Skip to content

Commit

Permalink
Merge pull request #1907 from ergoplatform/p2s-rule
Browse files Browse the repository at this point in the history
API method to derive custom tracking rule from P2S address
  • Loading branch information
kushti authored Sep 8, 2023
2 parents 3b4db24 + 66c0d99 commit a4072cc
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
35 changes: 35 additions & 0 deletions src/main/resources/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5550,6 +5550,41 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'

/scan/p2sRule:
post:
security:
- ApiKeyAuth: [api_key]
summary: Create and register a scan to track P2S address provided
operationId: scriptP2SRule
tags:
- scan
requestBody:
required: true
content:
application/json:
schema:
type: string
example: '4MQyML64GnzMxZgm'
responses:
'200':
description: Id of custom scan generated and registered
content:
application/json:
schema:
$ref: '#/components/schemas/ScanId'
'400':
description: Bad source
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
default:
description: Error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'

/wallet/generateCommitments:
post:
security:
Expand Down
29 changes: 27 additions & 2 deletions src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import akka.http.scaladsl.server.Route
import io.circe.Encoder
import org.ergoplatform._
import org.ergoplatform.nodeView.wallet._
import org.ergoplatform.nodeView.wallet.scanning.ScanRequest
import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest, ScanWalletInteraction}
import org.ergoplatform.settings.ErgoSettings
import scorex.core.api.http.ApiError.BadRequest
import scorex.core.api.http.ApiResponse
import scorex.core.settings.RESTApiSettings

import scala.util.{Failure, Success}
import ScanEntities._
import org.ergoplatform.ErgoBox.R1
import org.ergoplatform.wallet.Constants.ScanId
import sigmastate.Values.ByteArrayConstant
import sigmastate.serialization.ErgoTreeSerializer

/**
* This class contains methods to register / deregister and list external scans, and also to serve them.
Expand All @@ -40,7 +43,8 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings)
unspentR ~
spentR ~
stopTrackingR ~
addBoxR
addBoxR ~
p2sRuleR
}

def registerR: Route = (path("register") & post & entity(as[ScanRequest])) { request =>
Expand Down Expand Up @@ -91,4 +95,25 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings)
case Success(_) => ApiResponse(scanIdsBox.box.id)
}
}

/**
* API method to get tracking rule corresponding to p2s address
*/
def p2sRuleR: Route = (path("p2sRule") & post & entity(as[String])) { p2sRaw =>
val p2s = fromJsonOrPlain(p2sRaw)
addressEncoder.fromString(p2s) match {
case Success(p2sAddr) =>
val script = p2sAddr.script
val scriptBytes = ByteArrayConstant(ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(script))
val trackingRule = EqualsScanningPredicate(R1, scriptBytes)
val request = ScanRequest(p2s, trackingRule, Some(ScanWalletInteraction.Off), Some(true))
withWalletOp(_.addScan(request).map(_.response)) {
case Failure(e) => BadRequest(s"Bad request $request. ${Option(e.getMessage).getOrElse(e.toString)}")
case Success(app) => ApiResponse(ScanIdWrapper(app.scanId))
}
case Failure(e) => BadRequest(s"Can't parse $p2s. ${Option(e.getMessage).getOrElse(e.toString)}")
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ class ScanApiRouteSpec extends AnyFlatSpec
}
}


it should "stop tracking a box" in {
val scanIdBoxId = ScanIdBoxId(ScanId @@ (51: Short), ADKey @@ Random.randomBytes(32))

Expand All @@ -261,4 +260,16 @@ class ScanApiRouteSpec extends AnyFlatSpec
}
}

it should "generate scan for p2s rule" in {
Post(prefix + "/p2sRule", "Ms7smJmdbakqfwNo") ~> route ~> check {
status shouldBe StatusCodes.OK
val res = responseAs[Json]
res.hcursor.downField("scanId").as[Int].toOption.isDefined shouldBe true
}

Post(prefix + "/p2sRule", "s7smJmdbakqfwNo") ~> route ~> check {
status shouldBe StatusCodes.BadRequest
}
}

}

0 comments on commit a4072cc

Please sign in to comment.