Exemplo n.º 1
0
 def get_new_puzzle(self) -> Program:
     if (self.rl_info.limit is None or self.rl_info.interval is None
             or self.rl_info.user_pubkey is None
             or self.rl_info.admin_pubkey is None
             or self.rl_info.rl_origin_id is None):
         raise ValueError("One or more of the RL info fields is None")
     return rl_puzzle_for_pk(
         pubkey=self.rl_info.user_pubkey,
         rate_amount=self.rl_info.limit,
         interval_time=self.rl_info.interval,
         origin_id=self.rl_info.rl_origin_id,
         clawback_pk=self.rl_info.admin_pubkey,
     )
Exemplo n.º 2
0
    async def rl_generate_signed_aggregation_transaction(
            self, rl_info, consolidating_coin, rl_parent, rl_coin):
        if (rl_info.limit is None or rl_info.interval is None
                or rl_info.user_pubkey is None
                or rl_info.admin_pubkey is None):
            raise ValueError("One or more of the elements of rl_info is None")
        if self.rl_coin_record is None:
            raise ValueError("Rl coin record is None")

        list_of_coin_solutions = []
        self.rl_coin_record = await self._get_rl_coin_record()
        pubkey, secretkey = await self.get_keys(
            self.rl_coin_record.coin.puzzle_hash)
        # Spend wallet coin
        puzzle = rl_puzzle_for_pk(
            rl_info.user_pubkey,
            rl_info.limit,
            rl_info.interval,
            rl_info.rl_origin_id,
            rl_info.admin_pubkey,
        )

        solution = rl_make_solution_mode_2(
            rl_coin.puzzle_hash,
            consolidating_coin.parent_coin_info,
            consolidating_coin.puzzle_hash,
            consolidating_coin.amount,
            rl_coin.parent_coin_info,
            rl_coin.amount,
            rl_parent.amount,
            rl_parent.parent_coin_info,
        )
        signature = AugSchemeMPL.sign(secretkey, solution.get_tree_hash())
        rl_spend = CoinSolution(self.rl_coin_record.coin, puzzle, solution)

        list_of_coin_solutions.append(rl_spend)

        # Spend consolidating coin
        puzzle = rl_make_aggregation_puzzle(
            self.rl_coin_record.coin.puzzle_hash)
        solution = rl_make_aggregation_solution(
            consolidating_coin.name(),
            self.rl_coin_record.coin.parent_coin_info,
            self.rl_coin_record.coin.amount,
        )
        agg_spend = CoinSolution(consolidating_coin, puzzle, solution)

        list_of_coin_solutions.append(agg_spend)
        aggsig = AugSchemeMPL.aggregate([signature])

        return SpendBundle(list_of_coin_solutions, aggsig)
Exemplo n.º 3
0
 def puzzle_for_pk(self, pk) -> Optional[Program]:
     if self.rl_info.initialized is False:
         return None
     if (self.rl_info.limit is None or self.rl_info.interval is None
             or self.rl_info.user_pubkey is None
             or self.rl_info.admin_pubkey is None
             or self.rl_info.rl_origin_id is None):
         return None
     return rl_puzzle_for_pk(
         pubkey=self.rl_info.user_pubkey,
         rate_amount=self.rl_info.limit,
         interval_time=self.rl_info.interval,
         origin_id=self.rl_info.rl_origin_id,
         clawback_pk=self.rl_info.admin_pubkey,
     )
Exemplo n.º 4
0
    async def rl_generate_unsigned_transaction(self, to_puzzlehash, amount,
                                               fee) -> List[CoinSolution]:
        spends = []
        assert self.rl_coin_record is not None
        coin = self.rl_coin_record.coin
        puzzle_hash = coin.puzzle_hash
        pubkey = self.rl_info.user_pubkey
        rl_parent: Optional[Coin] = await self._get_rl_parent()
        if rl_parent is None:
            raise ValueError("No RL parent coin")

        # these lines make mypy happy

        assert pubkey is not None
        assert self.rl_info.limit is not None
        assert self.rl_info.interval is not None
        assert self.rl_info.rl_origin_id is not None
        assert self.rl_info.admin_pubkey is not None

        puzzle = rl_puzzle_for_pk(
            bytes(pubkey),
            self.rl_info.limit,
            self.rl_info.interval,
            self.rl_info.rl_origin_id,
            self.rl_info.admin_pubkey,
        )

        solution = solution_for_rl(
            coin.parent_coin_info,
            puzzle_hash,
            coin.amount,
            to_puzzlehash,
            amount,
            rl_parent.parent_coin_info,
            rl_parent.amount,
            self.rl_info.interval,
            self.rl_info.limit,
            fee,
        )

        spends.append(CoinSolution(coin, puzzle, solution))
        return spends
Exemplo n.º 5
0
 def generate_unsigned_clawback_transaction(self, clawback_coin: Coin,
                                            clawback_puzzle_hash: bytes32,
                                            fee):
     if (self.rl_info.limit is None or self.rl_info.interval is None
             or self.rl_info.user_pubkey is None
             or self.rl_info.admin_pubkey is None):
         raise ValueError("One ore more of the elements of rl_info is None")
     spends = []
     coin = clawback_coin
     if self.rl_info.rl_origin is None:
         raise ValueError("Origin not initialized")
     puzzle = rl_puzzle_for_pk(
         self.rl_info.user_pubkey,
         self.rl_info.limit,
         self.rl_info.interval,
         self.rl_info.rl_origin.name(),
         self.rl_info.admin_pubkey,
     )
     solution = make_clawback_solution(clawback_puzzle_hash,
                                       clawback_coin.amount, fee)
     spends.append((puzzle, CoinSolution(coin, puzzle, solution)))
     return spends
Exemplo n.º 6
0
    async def set_user_info(
        self,
        interval: uint64,
        limit: uint64,
        origin_parent_id: str,
        origin_puzzle_hash: str,
        origin_amount: uint64,
        admin_pubkey: str,
    ) -> None:
        admin_pubkey_bytes = hexstr_to_bytes(admin_pubkey)

        assert self.rl_info.user_pubkey is not None
        origin = Coin(
            hexstr_to_bytes(origin_parent_id),
            hexstr_to_bytes(origin_puzzle_hash),
            origin_amount,
        )
        rl_puzzle = rl_puzzle_for_pk(
            pubkey=self.rl_info.user_pubkey,
            rate_amount=limit,
            interval_time=interval,
            origin_id=origin.name(),
            clawback_pk=admin_pubkey_bytes,
        )

        rl_puzzle_hash = rl_puzzle.get_tree_hash()

        new_rl_info = RLInfo(
            "user",
            admin_pubkey_bytes,
            self.rl_info.user_pubkey,
            limit,
            interval,
            origin,
            origin.name(),
            rl_puzzle_hash,
            True,
        )
        rl_puzzle_hash = rl_puzzle.get_tree_hash()
        if await self.wallet_state_manager.puzzle_store.puzzle_hash_exists(
                rl_puzzle_hash):
            raise ValueError(
                "Cannot create multiple Rate Limited wallets under the same keys. This will change in a future release."
            )
        user_pubkey: G1Element = G1Element.from_bytes(self.rl_info.user_pubkey)
        index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(
            user_pubkey)
        assert index is not None
        record = DerivationRecord(
            index,
            rl_puzzle_hash,
            user_pubkey,
            WalletType.RATE_LIMITED,
            self.id(),
        )

        aggregation_puzzlehash = self.rl_get_aggregation_puzzlehash(
            new_rl_info.rl_puzzle_hash)
        record2 = DerivationRecord(
            index + 1,
            aggregation_puzzlehash,
            user_pubkey,
            WalletType.RATE_LIMITED,
            self.id(),
        )
        await self.wallet_state_manager.puzzle_store.add_derivation_paths(
            [record, record2])
        self.wallet_state_manager.set_coin_with_puzzlehash_created_callback(
            aggregation_puzzlehash, self.aggregate_this_coin)

        data_str = json.dumps(new_rl_info.to_json_dict())
        new_wallet_info = WalletInfo(self.id(), self.wallet_info.name,
                                     self.type(), data_str)
        await self.wallet_state_manager.user_store.update_wallet(
            new_wallet_info, False)
        await self.wallet_state_manager.add_new_wallet(self, self.id())
        self.wallet_info = new_wallet_info
        self.rl_info = new_rl_info
Exemplo n.º 7
0
    async def admin_create_coin(
        self,
        interval: uint64,
        limit: uint64,
        user_pubkey: str,
        amount: uint64,
        fee: uint64,
    ) -> bool:
        coins = await self.wallet_state_manager.main_wallet.select_coins(amount
                                                                         )
        if coins is None:
            return False

        origin = coins.copy().pop()
        origin_id = origin.name()

        user_pubkey_bytes = hexstr_to_bytes(user_pubkey)

        assert self.rl_info.admin_pubkey is not None

        rl_puzzle = rl_puzzle_for_pk(
            pubkey=user_pubkey_bytes,
            rate_amount=limit,
            interval_time=interval,
            origin_id=origin_id,
            clawback_pk=self.rl_info.admin_pubkey,
        )

        rl_puzzle_hash = rl_puzzle.get_tree_hash()
        index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(
            G1Element.from_bytes(self.rl_info.admin_pubkey))

        assert index is not None
        record = DerivationRecord(
            index,
            rl_puzzle_hash,
            G1Element.from_bytes(self.rl_info.admin_pubkey),
            WalletType.RATE_LIMITED,
            self.id(),
        )
        await self.wallet_state_manager.puzzle_store.add_derivation_paths(
            [record])

        spend_bundle = await self.main_wallet.generate_signed_transaction(
            amount, rl_puzzle_hash, fee, origin_id, coins)
        if spend_bundle is None:
            return False

        await self.main_wallet.push_transaction(spend_bundle)
        new_rl_info = RLInfo(
            "admin",
            self.rl_info.admin_pubkey,
            user_pubkey_bytes,
            limit,
            interval,
            origin,
            origin.name(),
            rl_puzzle_hash,
            True,
        )

        data_str = json.dumps(new_rl_info.to_json_dict())
        new_wallet_info = WalletInfo(self.id(), self.wallet_info.name,
                                     self.type(), data_str)
        await self.wallet_state_manager.user_store.update_wallet(
            new_wallet_info, False)
        await self.wallet_state_manager.add_new_wallet(self, self.id())
        self.wallet_info = new_wallet_info
        self.rl_info = new_rl_info

        return True