# Path: pypeerassets/protocol.py
# class IssueMode(Enum):
# 
#     NONE = 0x00
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L19
#     # No issuance allowed.
# 
#     CUSTOM = 0x01
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L20
#     # Custom issue mode, verified by client aware of this.
# 
#     ONCE = 0x02
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L21
#     # A single card_issue transaction allowed.
# 
#     MULTI = 0x04
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L22
#     # Multiple card_issue transactions allowed.
# 
#     MONO = 0x08
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L23
#     # All card transaction amounts are equal to 1.
# 
#     UNFLUSHABLE = 0x10
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L24
#     # The UNFLUSHABLE issue mode invalidates any card transfer transaction except for the card issue transaction.
#     # Meaning that only the issuing entity is able to change the balance of a specific address.
#     # To correctly calculate the balance of a PeerAssets addres a client should only consider the card transfer
#     # transactions originating from the deck owner.
# 
#     SUBSCRIPTION = 0x34  # SUBSCRIPTION (34 = 20 | 4 | 10)
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L26
#     # The SUBSCRIPTION issue mode marks an address holding tokens as subscribed for a limited timeframe. This timeframe is
#     # defined by the balance of the account and the time at which the first cards of this token are received.
#     # To check validity of a subscription one should take the timestamp of the first received cards and add the address' balance to it in hours.
# 
#     SINGLET = 0x0a  # SINGLET is a combination of ONCE and MONO (2 | 8)
# 
# Path: pypeerassets/provider/rpcnode.py
# class RpcNode(Client, Provider):
#     '''JSON-RPC connection to local Peercoin node'''
# 
#     def select_inputs(self, address: str, amount: int) -> dict:
#         '''finds apropriate utxo's to include in rawtx, while being careful
#         to never spend old transactions with a lot of coin age.
#         Argument is intiger, returns list of apropriate UTXO's'''
# 
#         utxos = []
#         utxo_sum = Decimal(0)
#         for tx in sorted(self.listunspent(address=address), key=itemgetter('confirmations')):
# 
#             if tx["address"] not in (self.pa_parameters.P2TH_addr,
#                                      self.pa_parameters.test_P2TH_addr):
# 
#                 utxos.append(
#                         MutableTxIn(txid=tx['txid'],
#                                     txout=tx['vout'],
#                                     sequence=Sequence.max(),
#                                     script_sig=ScriptSig.empty())
#                          )
# 
#                 utxo_sum += Decimal(tx["amount"])
#                 if utxo_sum >= amount:
#                     return {'utxos': utxos, 'total': utxo_sum}
# 
#         if utxo_sum < amount:
#             raise InsufficientFunds("Insufficient funds.")
# 
#         raise Exception("undefined behavior :.(")
# 
#     @property
#     def is_testnet(self) -> bool:
#         '''check if node is configured to use testnet or mainnet'''
# 
#         if self.getinfo()["testnet"] is True:
#             return True
#         else:
#             return False
# 
#     @property
#     def network(self) -> str:
#         '''return which network is the node operating on.'''
# 
#         if self.is_testnet:
#             return "tppc"
#         else:
#             return "ppc"
# 
#     def listunspent(
#         self,
#         address: str="",
#         minconf: int=1,
#         maxconf: int=999999,
#     ) -> list:
#         '''list UTXOs
#         modified version to allow filtering by address.
#         '''
#         if address:
#             return self.req("listunspent", [minconf, maxconf, [address]])
# 
#         return self.req("listunspent", [minconf, maxconf])
# 
# Path: pypeerassets/transactions.py
# def sign_transaction(provider: Provider, unsigned: MutableTransaction,
#                      key: Kutil) -> Transaction:
#     '''sign transaction with Kutil'''
# 
#     parent_outputs = [find_parent_outputs(provider, i) for i in unsigned.ins]
#     return key.sign_transaction(parent_outputs, unsigned)


import time
import pypeerassets as pa
from pypeerassets.protocol import IssueMode
from pypeerassets.provider import RpcNode
from pypeerassets.transactions import sign_transaction

if __name__ == "__main__":

    # Deck Spawn

    print("Build, sign and send the Friendly Co. Deck spawning transaction...")

    rpc_node = RpcNode(testnet=True, username=RPC_USERNAME, password=RPC_PASSWORD)

    friendly_co_key = pa.Kutil(
        network="tppc",
        from_wif=rpc_node.dumpprivkey(FRIENDLY_CO),
    )

    deck = pa.Deck(
        name="Friendly Co. Deck",
        number_of_decimals=0,
        issue_mode=IssueMode.ONCE.value,
        network="tppc",
        production=False,
        version=1,
        issuer=FRIENDLY_CO,
    )

    deck_spawn_tx = pa.deck_spawn(
        provider=rpc_node,
        deck=deck,
        inputs=rpc_node.select_inputs(FRIENDLY_CO, 0.02),
        change_address=FRIENDLY_CO,
    )

# Path: pypeerassets/protocol.py
# class IssueMode(Enum):
# 
#     NONE = 0x00
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L19
#     # No issuance allowed.
# 
#     CUSTOM = 0x01
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L20
#     # Custom issue mode, verified by client aware of this.
# 
#     ONCE = 0x02
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L21
#     # A single card_issue transaction allowed.
# 
#     MULTI = 0x04
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L22
#     # Multiple card_issue transactions allowed.
# 
#     MONO = 0x08
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L23
#     # All card transaction amounts are equal to 1.
# 
#     UNFLUSHABLE = 0x10
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L24
#     # The UNFLUSHABLE issue mode invalidates any card transfer transaction except for the card issue transaction.
#     # Meaning that only the issuing entity is able to change the balance of a specific address.
#     # To correctly calculate the balance of a PeerAssets addres a client should only consider the card transfer
#     # transactions originating from the deck owner.
# 
#     SUBSCRIPTION = 0x34  # SUBSCRIPTION (34 = 20 | 4 | 10)
#     # https://github.com/PeerAssets/rfcs/blob/master/0001-peerassets-transaction-specification.proto#L26
#     # The SUBSCRIPTION issue mode marks an address holding tokens as subscribed for a limited timeframe. This timeframe is
#     # defined by the balance of the account and the time at which the first cards of this token are received.
#     # To check validity of a subscription one should take the timestamp of the first received cards and add the address' balance to it in hours.
# 
#     SINGLET = 0x0a  # SINGLET is a combination of ONCE and MONO (2 | 8)
# 
# Path: pypeerassets/provider/rpcnode.py
# class RpcNode(Client, Provider):
#     '''JSON-RPC connection to local Peercoin node'''
# 
#     def select_inputs(self, address: str, amount: int) -> dict:
#         '''finds apropriate utxo's to include in rawtx, while being careful
#         to never spend old transactions with a lot of coin age.
#         Argument is intiger, returns list of apropriate UTXO's'''
# 
#         utxos = []
#         utxo_sum = Decimal(0)
#         for tx in sorted(self.listunspent(address=address), key=itemgetter('confirmations')):
# 
#             if tx["address"] not in (self.pa_parameters.P2TH_addr,
#                                      self.pa_parameters.test_P2TH_addr):
# 
#                 utxos.append(
#                         MutableTxIn(txid=tx['txid'],
#                                     txout=tx['vout'],
#                                     sequence=Sequence.max(),
#                                     script_sig=ScriptSig.empty())
#                          )
# 
#                 utxo_sum += Decimal(tx["amount"])
#                 if utxo_sum >= amount:
#                     return {'utxos': utxos, 'total': utxo_sum}
# 
#         if utxo_sum < amount:
#             raise InsufficientFunds("Insufficient funds.")
# 
#         raise Exception("undefined behavior :.(")
# 
#     @property
#     def is_testnet(self) -> bool:
#         '''check if node is configured to use testnet or mainnet'''
# 
#         if self.getinfo()["testnet"] is True:
#             return True
#         else:
#             return False
# 
#     @property
#     def network(self) -> str:
#         '''return which network is the node operating on.'''
# 
#         if self.is_testnet:
#             return "tppc"
#         else:
#             return "ppc"
# 
#     def listunspent(
#         self,
#         address: str="",
#         minconf: int=1,
#         maxconf: int=999999,
#     ) -> list:
#         '''list UTXOs
#         modified version to allow filtering by address.
#         '''
#         if address:
#             return self.req("listunspent", [minconf, maxconf, [address]])
# 
#         return self.req("listunspent", [minconf, maxconf])
# 
# Path: pypeerassets/transactions.py
# def sign_transaction(provider: Provider, unsigned: MutableTransaction,
#                      key: Kutil) -> Transaction:
#     '''sign transaction with Kutil'''
# 
#     parent_outputs = [find_parent_outputs(provider, i) for i in unsigned.ins]
#     return key.sign_transaction(parent_outputs, unsigned)


# Path: examples/once_issue_mode_example.py
import time
import pypeerassets as pa
from pypeerassets.protocol import IssueMode
from pypeerassets.provider import RpcNode
from pypeerassets.transactions import sign_transaction


if __name__ == "__main__":

    # Deck Spawn

    print("Build, sign and send the Friendly Co. Deck spawning transaction...")

    rpc_node = RpcNode(testnet=True, username=RPC_USERNAME, password=RPC_PASSWORD)

    friendly_co_key = pa.Kutil(
        network="tppc",
        from_wif=rpc_node.dumpprivkey(FRIENDLY_CO),
    )

    deck = pa.Deck(
        name="Friendly Co. Deck",
        number_of_decimals=0,
        issue_mode=IssueMode.ONCE.value,
        network="tppc",
        production=False,
        version=1,
        issuer=FRIENDLY_CO,
    )

    deck_spawn_tx = pa.deck_spawn(
        provider=rpc_node,
        deck=deck,
        inputs=rpc_node.select_inputs(FRIENDLY_CO, 0.02),
        change_address=FRIENDLY_CO,
    )

    deck_spawn_tx = sign_transaction(rpc_node, deck_spawn_tx, friendly_co_key)