Skip to content

Commit

Permalink
Added new builder methods that take lists and removed "at least 1" re…
Browse files Browse the repository at this point in the history
…quirement
  • Loading branch information
satsen committed Oct 20, 2024
1 parent 9aafd8a commit b22c0f2
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 19 deletions.
29 changes: 27 additions & 2 deletions lib-api/src/main/java/org/ergoplatform/appkit/OutBoxBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import org.ergoplatform.SigmaConstants;
import org.ergoplatform.sdk.ErgoToken;
import sigmastate.SInt;

import java.util.List;

/**
* This interface is used to build a new output box, which can be included
Expand Down Expand Up @@ -32,13 +35,22 @@ public interface OutBoxBuilder {
* Configures amounts for one or more tokens (up to {@link SigmaConstants.MaxTokens}).
* Each Ergo box can store zero or more tokens (aka assets).
*
* @param tokens one or more tokens to be added to the constructed output box.
* @param tokens tokens to be added to the constructed output box.
* @see ErgoToken
*/
OutBoxBuilder tokens(ErgoToken... tokens);

/**
* Mints new token according to https://github.com/ergoplatform/eips/blob/master/eip-0004.md
* Configures amounts for tokens (up to {@link SigmaConstants.MaxTokens}).
* Each Ergo box can store zero or more tokens (aka assets).
*
* @param tokens tokens to be added to the constructed output box.
* @see ErgoToken
*/
OutBoxBuilder tokens(List<ErgoToken> tokens);

/**
* Mints new token according to <a href="https://github.com/ergoplatform/eips/blob/master/eip-0004.md">EIP-0004</a>
*
* @param token token to mint
* @see Eip4Token and Eip4TokenBuilder
Expand All @@ -58,6 +70,19 @@ public interface OutBoxBuilder {
*/
OutBoxBuilder registers(ErgoValue<?>... registers);

/**
* Configures one or more optional registers of the output box.
* Each box have 4 mandatory registers holding value of NanoErgs, guarding script,
* tokens, creation info.
* Optional (aka non-mandatory) registers numbered from index 4 up to 9.
*
* @param registers list of optional register values,
* where registers[0] corresponds to R4, registers[1] - R5, etc.
* @see ErgoValue
* @see org.ergoplatform.ErgoBox.NonMandatoryRegisterId
*/
OutBoxBuilder registers(List<ErgoValue<?>> registers);

/**
* Configure the height when the transaction containing the box was created.
* This height, when explicitly specified, should not exceed height of the block,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ public interface UnsignedTransactionBuilder {
UnsignedTransactionBuilder preHeader(PreHeader ph);

/**
* Adds input boxes to an already specified list of inputs or, if no input boxes defined yet,
* @see #addInputs(List)
*/
UnsignedTransactionBuilder addInputs(InputBox... boxes);

/**
* Adds input boxes to an already specified list of inputs or, if no input boxes are defined yet,
* as the boxes to spend. The order is preserved.
* The boxes that will be spent by the transaction when it will be included in a block.
*
Expand All @@ -33,40 +38,50 @@ public interface UnsignedTransactionBuilder {
* as {@link OutBox} and then {@link OutBox#convertToInputWith(String, short) converted} to
* {@link InputBox}.
*/
UnsignedTransactionBuilder addInputs(InputBox... boxes);
UnsignedTransactionBuilder addInputs(List<InputBox> boxes);

/**
* @deprecated use {@link #addInputs(InputBox...)}
* @deprecated Use {@link #addInputs(List)} instead.
*/
@Deprecated
UnsignedTransactionBuilder boxesToSpend(List<InputBox> boxes);

/**
* @see #addDataInputs(List)
*/
UnsignedTransactionBuilder addDataInputs(InputBox... boxes);

/**
* @deprecated Use {@link #addDataInputs(List)} instead.
*/
@Deprecated
UnsignedTransactionBuilder withDataInputs(List<InputBox> boxes);

/**
* Adds input boxes to an already specified list of data inputs or, if no data input boxes
* defined yet, set the boxes as the data input boxes to be used. The order is preserved.
* are defined yet, set the boxes as the data input boxes to be used. The order is preserved.
*
* @param boxes list of boxes to be used as data-inputs by the transaction. The boxes can either be
* {@link BlockchainContext#getBoxesById(String...) obtained} from context of created from
* scratch
* as {@link OutBox} and then {@link OutBox#convertToInputWith(String, short) converted} to
* {@link InputBox}.
*/
UnsignedTransactionBuilder addDataInputs(InputBox... boxes);
UnsignedTransactionBuilder addDataInputs(List<InputBox> boxes);

/**
* @deprecated use {@link #addDataInputs(InputBox...)}
* @deprecated use {@link #addOutputs(OutBox...)}
*/
@Deprecated
UnsignedTransactionBuilder withDataInputs(List<InputBox> boxes);
UnsignedTransactionBuilder outputs(OutBox... outputs);

/**
* @deprecated use {@link #addOutputs(OutBox...)}
* @see #addOutputs(List)
*/
@Deprecated
UnsignedTransactionBuilder outputs(OutBox... outputs);
UnsignedTransactionBuilder addOutputs(OutBox... outBoxes);

/**
* Adds output boxes to an already specified list of outputs or, if no output boxes defined yet,
* Adds output boxes to an already specified list of outputs or, if no output boxes are defined yet,
* as the boxes to be output. The order is preserved.
* After this transaction is {@link UnsignedTransactionBuilder#build() built},
* {@link ErgoProver#sign(UnsignedTransaction)} signed,
Expand All @@ -75,7 +90,7 @@ public interface UnsignedTransactionBuilder {
*
* @param outBoxes output boxes created by the transaction
*/
UnsignedTransactionBuilder addOutputs(OutBox... outBoxes);
UnsignedTransactionBuilder addOutputs(List<OutBox> outBoxes);

/**
* Adds transaction fee output.
Expand All @@ -84,19 +99,24 @@ public interface UnsignedTransactionBuilder {
*/
UnsignedTransactionBuilder fee(long feeAmount);

/**
* @see #tokensToBurn(List)
*/
UnsignedTransactionBuilder tokensToBurn(ErgoToken... tokens);

/**
* Configures amounts for tokens to be burnt.
* Each Ergo box can store zero or more tokens (aka assets).
* In contrast to strict requirement on ERG balance between transaction inputs and outputs,
* the amounts of output tokens can be less then the amounts of input tokens.
* the amounts of output tokens can be less than the amounts of input tokens.
* This is interpreted as token burning i.e. reducing the total amount of tokens in
* circulation in the blockchain.
* Note, once issued/burnt, the amount of tokens in circulation cannot be increased.
*
* @param tokens one or more tokens to be burnt as part of the transaction.
* @see ErgoToken
*/
UnsignedTransactionBuilder tokensToBurn(ErgoToken... tokens);
UnsignedTransactionBuilder tokensToBurn(List<ErgoToken> tokens);

/**
* Adds change output to the specified address if needed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,22 @@ class OutBoxBuilderImpl(_txB: UnsignedTransactionBuilderImpl) extends OutBoxBuil
}

override def tokens(tokens: ErgoToken*): OutBoxBuilderImpl = {
require(tokens.nonEmpty, "At least one token should be specified")
val maxTokens = SigmaConstants.MaxTokens.value
require(tokens.size <= maxTokens, SigmaConstants.MaxTokens.description + s": $maxTokens")
_tokens ++= tokens
this
}

override def tokens(tokens: java.util.List[ErgoToken]): OutBoxBuilderImpl = {
val maxTokens = SigmaConstants.MaxTokens.value
require(tokens.size <= maxTokens, SigmaConstants.MaxTokens.description + s": $maxTokens")
val iterator = tokens.iterator()
while (iterator.hasNext) {
_tokens += iterator.next
}
this
}

override def mintToken(token: Eip4Token): OutBoxBuilder = {
val tokenNameVal = token.getMintingBoxR4
val tokenDescVal = token.getMintingBoxR5
Expand Down Expand Up @@ -70,6 +79,16 @@ class OutBoxBuilderImpl(_txB: UnsignedTransactionBuilderImpl) extends OutBoxBuil
this
}

override def registers(registers: java.util.List[ErgoValue[_]]): OutBoxBuilderImpl = {
InternalUtil.checkArgument(!registers.isEmpty,
"At least one register should be specified": Any)
_registers.clear()
val iterator = registers.iterator()
while (iterator.hasNext)
_registers += iterator.next()
this
}

override def creationHeight(height: Int): OutBoxBuilder = {
_creationHeightOpt = Some(height)
this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,19 @@ class UnsignedTransactionBuilderImpl(val _ctx: BlockchainContextImpl) extends Un
this
}

override def addInputs(boxes: util.List[InputBox]): UnsignedTransactionBuilder = {
val iterator = boxes.iterator()
while (iterator.hasNext) {
iterator.next() match {
case b: InputBoxImpl => _inputs.add(b)
}
}
this
}

override def boxesToSpend(inputBoxes: List[InputBox]): UnsignedTransactionBuilder = {
require(_inputs.isEmpty, "inputs already specified")
addInputs(JavaHelpers.toIndexedSeq(inputBoxes): _*)
this
addInputs(inputBoxes)
}

override def addDataInputs(boxes: InputBox*): UnsignedTransactionBuilder = {
Expand All @@ -57,6 +66,16 @@ class UnsignedTransactionBuilderImpl(val _ctx: BlockchainContextImpl) extends Un
this
}

override def addDataInputs(boxes: util.List[InputBox]): UnsignedTransactionBuilder = {
val iterator = boxes.iterator()
while (iterator.hasNext) {
iterator.next() match {
case b: InputBoxImpl => _dataInputs.add(b)
}
}
this
}

override def addOutputs(outBoxes: OutBox*): UnsignedTransactionBuilder = {
outBoxes.foreach { case b: OutBoxImpl =>
_outputs.add(b)
Expand All @@ -70,6 +89,16 @@ class UnsignedTransactionBuilderImpl(val _ctx: BlockchainContextImpl) extends Un
this
}

override def addOutputs(outBoxes: util.List[OutBox]): UnsignedTransactionBuilder = {
val iterator = outBoxes.iterator()
while (iterator.hasNext) {
iterator.next() match {
case b: OutBoxImpl => _outputs.add(b)
}
}
this
}

override def fee(feeAmount: Long): UnsignedTransactionBuilder = {
require(_feeAmount.isEmpty, "Fee already defined")
_feeAmount = Some(feeAmount)
Expand All @@ -86,6 +115,12 @@ class UnsignedTransactionBuilderImpl(val _ctx: BlockchainContextImpl) extends Un
this
}

override def tokensToBurn(tokens: util.List[ErgoToken]): UnsignedTransactionBuilder = {
require(_tokensToBurn.isEmpty, "Tokens to burn already specified.")
_tokensToBurn = Some(new util.ArrayList[ErgoToken](tokens))
this
}

override def sendChangeTo(changeAddress: ErgoAddress): UnsignedTransactionBuilder = {
require(_changeAddress.isEmpty, "Change address is already specified")
_changeAddress = Some(changeAddress)
Expand Down

0 comments on commit b22c0f2

Please sign in to comment.