|
1 | 1 | # Copyright ©, 2022-present, Lightspark Group, Inc. - All Rights Reserved |
2 | 2 |
|
3 | 3 | import logging |
| 4 | +import re |
4 | 5 | from dataclasses import dataclass |
5 | 6 | from datetime import datetime, timedelta, timezone |
6 | 7 | from hashlib import sha256 |
|
45 | 46 | from lightspark.objects.PaymentDirection import PaymentDirection |
46 | 47 | from lightspark.objects.PaymentRequestData import PaymentRequestData |
47 | 48 | from lightspark.objects.Permission import Permission |
| 49 | +from lightspark.objects.RegionCode import RegionCode |
48 | 50 | from lightspark.objects.RiskRating import RiskRating |
49 | 51 | from lightspark.objects.TransactionStatus import TransactionStatus |
| 52 | +from lightspark.objects.UmaInvitation import UmaInvitation |
| 53 | +from lightspark.objects.UmaInvitation import from_json as UmaInvitation_from_json |
50 | 54 | from lightspark.objects.WithdrawalMode import WithdrawalMode |
51 | 55 | from lightspark.objects.WithdrawalRequest import WithdrawalRequest |
52 | 56 | from lightspark.objects.WithdrawalRequest import ( |
53 | 57 | from_json as WithdrawalRequest_from_json, |
54 | 58 | ) |
55 | 59 | from lightspark.requests.requester import Requester |
56 | 60 | from lightspark.scripts.bitcoin_fee_estimate import BITCOIN_FEE_ESTIMATE_QUERY |
| 61 | +from lightspark.scripts.claim_uma_invitation import ( |
| 62 | + CLAIM_UMA_INVITATION_MUTATION, |
| 63 | + CLAIM_UMA_INVITATION_WITH_INCENTIVES_MUTATION, |
| 64 | +) |
57 | 65 | from lightspark.scripts.create_api_token import CREATE_API_TOKEN_MUTATION |
58 | 66 | from lightspark.scripts.create_invoice import CREATE_INVOICE_MUTATION |
59 | 67 | from lightspark.scripts.create_lnurl_invoice import CREATE_LNURL_INVOICE_MUTATION |
|
64 | 72 | from lightspark.scripts.create_test_mode_payment import ( |
65 | 73 | CREATE_TEST_MODE_PAYMENT_MUTATION, |
66 | 74 | ) |
| 75 | +from lightspark.scripts.create_uma_invitation import ( |
| 76 | + CREATE_UMA_INVITATION_MUTATION, |
| 77 | + CREATE_UMA_INVITATION_WITH_INCENTIVES_MUTATION, |
| 78 | +) |
67 | 79 | from lightspark.scripts.create_uma_invoice import CREATE_UMA_INVOICE_MUTATION |
68 | 80 | from lightspark.scripts.current_account import CURRENT_ACCOUNT_QUERY |
69 | 81 | from lightspark.scripts.decoded_payment_request import DECODED_PAYMENT_REQUEST_QUERY |
70 | 82 | from lightspark.scripts.delete_api_token import DELETE_API_TOKEN_MUTATION |
| 83 | +from lightspark.scripts.fetch_uma_invitation import FETCH_UMA_INVITATION_QUERY |
71 | 84 | from lightspark.scripts.fund_node import FUND_NODE_MUTATION |
72 | 85 | from lightspark.scripts.lightning_fee_estimate_for_invoice import ( |
73 | 86 | LIGHTNING_FEE_ESTIMATE_FOR_INVOICE_QUERY, |
|
87 | 100 | from lightspark.scripts.send_payment import SEND_PAYMENT_MUTATION |
88 | 101 | from lightspark.utils.crypto import decrypt_private_key |
89 | 102 | from lightspark.utils.enums import parse_enum |
90 | | -from lightspark.utils.signing_key import SigningKey, Secp256k1SigningKey, RSASigningKey |
| 103 | +from lightspark.utils.signing_key import RSASigningKey, Secp256k1SigningKey, SigningKey |
91 | 104 |
|
92 | 105 | logger = logging.getLogger("lightspark") |
93 | 106 |
|
@@ -653,3 +666,138 @@ def outgoing_payments_for_invoice( |
653 | 666 | OutgoingPayment_from_json(self._requester, payment) |
654 | 667 | for payment in json["outgoing_payments_for_invoice"]["payments"] |
655 | 668 | ] |
| 669 | + |
| 670 | + def create_uma_invitation( |
| 671 | + self, |
| 672 | + inviter_uma: str, |
| 673 | + ) -> UmaInvitation: |
| 674 | + """ |
| 675 | + Creates a new UMA invitation. If you are part of the incentive program, you should use the |
| 676 | + `create_uma_invitation_with_incentives` method instead. |
| 677 | +
|
| 678 | + Args: |
| 679 | + inviter_uma: The UMA of the inviter. |
| 680 | + """ |
| 681 | + json = self._requester.execute_graphql( |
| 682 | + CREATE_UMA_INVITATION_MUTATION, |
| 683 | + { |
| 684 | + "inviter_uma": inviter_uma, |
| 685 | + }, |
| 686 | + ) |
| 687 | + return UmaInvitation_from_json( |
| 688 | + self._requester, json["create_uma_invitation"]["invitation"] |
| 689 | + ) |
| 690 | + |
| 691 | + def create_uma_invitation_with_incentives( |
| 692 | + self, |
| 693 | + inviter_uma: str, |
| 694 | + inviter_phone_number_e164: str, |
| 695 | + inviter_region: RegionCode, |
| 696 | + ) -> UmaInvitation: |
| 697 | + """ |
| 698 | + Creates a new UMA invitation with incentives. If you are not part of the incentive program, you should use the |
| 699 | + `create_uma_invitation` method instead. |
| 700 | +
|
| 701 | + Args: |
| 702 | + inviter_uma: The UMA of the inviter. |
| 703 | + inviter_phone_number_e164: The E.164 formatted phone number of the inviter. |
| 704 | + inviter_region: The region of the inviter. |
| 705 | + """ |
| 706 | + json = self._requester.execute_graphql( |
| 707 | + CREATE_UMA_INVITATION_WITH_INCENTIVES_MUTATION, |
| 708 | + { |
| 709 | + "inviter_uma": inviter_uma, |
| 710 | + "inviter_phone_hash": self._hash_phone_number( |
| 711 | + inviter_phone_number_e164 |
| 712 | + ), |
| 713 | + "inviter_region": inviter_region.name, |
| 714 | + }, |
| 715 | + ) |
| 716 | + return UmaInvitation_from_json( |
| 717 | + self._requester, json["create_uma_invitation_with_incentives"]["invitation"] |
| 718 | + ) |
| 719 | + |
| 720 | + def claim_uma_invitation( |
| 721 | + self, |
| 722 | + invitation_code: str, |
| 723 | + invitee_uma: str, |
| 724 | + ) -> None: |
| 725 | + """ |
| 726 | + Claims a UMA invitation. If you are part of the incentive program, you should use the |
| 727 | + `claim_uma_invitation_with_incentives` method instead. |
| 728 | +
|
| 729 | + Args: |
| 730 | + invitation_code: The invitation code of the invitation to claim. |
| 731 | + invitee_uma: The new UMA of the invitee. |
| 732 | + """ |
| 733 | + self._requester.execute_graphql( |
| 734 | + CLAIM_UMA_INVITATION_MUTATION, |
| 735 | + { |
| 736 | + "invitation_code": invitation_code, |
| 737 | + "invitee_uma": invitee_uma, |
| 738 | + }, |
| 739 | + ) |
| 740 | + |
| 741 | + def claim_uma_invitation_with_incentives( |
| 742 | + self, |
| 743 | + invitation_code: str, |
| 744 | + invitee_uma: str, |
| 745 | + invitee_phone_number_e164: str, |
| 746 | + invitee_region: RegionCode, |
| 747 | + ) -> None: |
| 748 | + """ |
| 749 | + Claims a UMA invitation with incentives. If you are not part of the incentive program, you should use the |
| 750 | + `claim_uma_invitation` method instead. |
| 751 | +
|
| 752 | + Args: |
| 753 | + invitation_code: The invitation code of the invitation to claim. |
| 754 | + invitee_uma: The new UMA of the invitee. |
| 755 | + invitee_phone_number_e164: The E.164 formatted phone number of the invitee. |
| 756 | + invitee_region: The region of the invitee. |
| 757 | + """ |
| 758 | + self._requester.execute_graphql( |
| 759 | + CLAIM_UMA_INVITATION_WITH_INCENTIVES_MUTATION, |
| 760 | + { |
| 761 | + "invitation_code": invitation_code, |
| 762 | + "invitee_uma": invitee_uma, |
| 763 | + "invitee_phone_hash": self._hash_phone_number( |
| 764 | + invitee_phone_number_e164 |
| 765 | + ), |
| 766 | + "invitee_region": invitee_region, |
| 767 | + }, |
| 768 | + ) |
| 769 | + |
| 770 | + def fetch_uma_invitation( |
| 771 | + self, |
| 772 | + invitation_code: str, |
| 773 | + ) -> Optional[UmaInvitation]: |
| 774 | + """ |
| 775 | + Fetches a UMA invitation by its invitation code. |
| 776 | +
|
| 777 | + Args: |
| 778 | + invitation_code: The invitation code of the invitation to fetch. |
| 779 | + """ |
| 780 | + json = self._requester.execute_graphql( |
| 781 | + FETCH_UMA_INVITATION_QUERY, |
| 782 | + { |
| 783 | + "invitation_code": invitation_code, |
| 784 | + }, |
| 785 | + ) |
| 786 | + |
| 787 | + return ( |
| 788 | + UmaInvitation_from_json(self._requester, json["uma_invitation_by_code"]) |
| 789 | + if json["uma_invitation_by_code"] |
| 790 | + else None |
| 791 | + ) |
| 792 | + |
| 793 | + def _hash_phone_number(self, phone_number_e164_format: str) -> str: |
| 794 | + match = E614_REGEX.search(phone_number_e164_format) |
| 795 | + if not match: |
| 796 | + raise LightsparkException( |
| 797 | + "InvalidPhoneNumber", "The phone number must follow the E.164 format." |
| 798 | + ) |
| 799 | + return sha256(phone_number_e164_format.encode()).hexdigest() |
| 800 | + |
| 801 | + |
| 802 | +# pylint: disable=anomalous-backslash-in-string |
| 803 | +E614_REGEX = re.compile("^\+?[1-9]\d{1,14}$") |
0 commit comments