2021-08-12 18:27:54 +00:00
|
|
|
"""
|
|
|
|
Utilities for managing subscription type resources for a Moonstream application.
|
|
|
|
"""
|
2024-02-21 20:47:42 +00:00
|
|
|
|
2021-08-12 18:27:54 +00:00
|
|
|
import argparse
|
|
|
|
import json
|
2021-08-12 19:23:21 +00:00
|
|
|
from typing import Dict, List, Optional
|
2021-08-12 18:27:54 +00:00
|
|
|
|
2021-11-01 13:41:25 +00:00
|
|
|
from bugout.data import BugoutResource, BugoutResources
|
2021-08-13 21:41:25 +00:00
|
|
|
from sqlalchemy.sql.expression import update
|
2021-08-12 18:27:54 +00:00
|
|
|
|
2021-08-12 19:23:21 +00:00
|
|
|
from ..data import SubscriptionTypeResourceData
|
2021-08-12 18:27:54 +00:00
|
|
|
from ..settings import (
|
2021-11-01 13:41:25 +00:00
|
|
|
BUGOUT_REQUEST_TIMEOUT_SECONDS,
|
2021-08-12 18:27:54 +00:00
|
|
|
MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
|
|
|
MOONSTREAM_APPLICATION_ID,
|
|
|
|
)
|
2021-11-01 13:41:25 +00:00
|
|
|
from ..settings import bugout_client as bc
|
2021-08-12 18:27:54 +00:00
|
|
|
|
2021-08-12 19:23:21 +00:00
|
|
|
CANONICAL_SUBSCRIPTION_TYPES = {
|
2021-12-01 22:18:22 +00:00
|
|
|
"ethereum_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="ethereum_smartcontract",
|
|
|
|
name="Ethereum smartcontracts",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="ethereum",
|
2021-12-01 22:18:22 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of Ethereum blockchain",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/ethereum/eth-diamond-purple.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2022-03-17 13:58:04 +00:00
|
|
|
active=True,
|
2021-12-01 22:18:22 +00:00
|
|
|
),
|
|
|
|
"polygon_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="polygon_smartcontract",
|
|
|
|
name="Polygon smartcontracts",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="polygon",
|
2021-12-01 22:18:22 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of Polygon blockchain",
|
2021-12-05 13:17:46 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/matic-token-inverted-icon.png",
|
2021-12-01 22:18:22 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
2022-08-10 17:06:47 +00:00
|
|
|
"mumbai_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="mumbai_smartcontract",
|
|
|
|
name="Mumbai smartcontracts",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="mumbai",
|
2022-08-10 17:06:47 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of Mumbai blockchain",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/matic-token-inverted-icon.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
2022-05-25 13:47:51 +00:00
|
|
|
"xdai_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="xdai_smartcontract",
|
|
|
|
name="XDai smartcontract",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="xdai",
|
2022-05-25 13:47:51 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of XDai blockchain.",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/xdai-token-logo.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
2023-03-06 15:58:25 +00:00
|
|
|
"wyrm_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="wyrm_smartcontract",
|
|
|
|
name="Wyrm smartcontract",
|
2023-04-20 12:55:22 +00:00
|
|
|
blockchain="wyrm",
|
2023-03-02 12:26:36 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
2023-03-06 15:58:25 +00:00
|
|
|
description="Contracts events and tx_calls of contract of Wyrm blockchain.",
|
2023-03-07 12:20:26 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/great-wyrm-network-logo.png",
|
2023-03-02 12:26:36 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
2023-08-28 23:48:47 +00:00
|
|
|
"zksync_era_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="zksync_era_smartcontract",
|
|
|
|
name="zkSync Era smartcontract",
|
|
|
|
blockchain="zksync_era",
|
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of zkSync Era blockchain.",
|
2023-08-30 12:58:50 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/zksync-era-token-logo.png",
|
2023-08-28 23:48:47 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
2023-07-13 14:37:42 +00:00
|
|
|
"zksync_era_testnet_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="zksync_era_testnet_smartcontract",
|
|
|
|
name="zkSync Era testnet smartcontract",
|
|
|
|
blockchain="zksync_era_testnet",
|
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of zkSync Era testnet blockchain.",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/zksync-era-testnet-token-logo.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
2024-02-21 20:47:42 +00:00
|
|
|
"arbitrum_nova_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="arbitrum_nova_smartcontract",
|
|
|
|
name="Arbitrum Nova smartcontract",
|
|
|
|
blockchain="arbitrum_nova",
|
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of Arbitrum Nova blockchain.",
|
2024-02-22 01:10:11 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/arbitrum-nova-token-logo.png",
|
2024-02-21 20:47:42 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
|
|
|
"arbitrum_sepolia_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="arbitrum_sepolia_smartcontract",
|
|
|
|
name="Arbitrum Sepolia smartcontract",
|
|
|
|
blockchain="arbitrum_sepolia",
|
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of Arbitrum Sepolia blockchain.",
|
2024-02-22 01:10:11 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/arbitrum-sepolia-token-logo.png",
|
2024-02-21 20:47:42 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
|
|
|
"xai_smartcontract": SubscriptionTypeResourceData(
|
|
|
|
id="xai_smartcontract",
|
|
|
|
name="Xai smartcontract",
|
|
|
|
blockchain="xai",
|
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Contracts events and tx_calls of contract of Xai blockchain.",
|
2024-02-22 01:10:11 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/xai-token-logo.png",
|
2024-02-21 20:47:42 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=True,
|
|
|
|
),
|
2021-08-12 19:23:21 +00:00
|
|
|
"ethereum_blockchain": SubscriptionTypeResourceData(
|
|
|
|
id="ethereum_blockchain",
|
|
|
|
name="Ethereum transactions",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="ethereum",
|
2021-09-08 17:41:25 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
2021-08-12 19:23:21 +00:00
|
|
|
description="Transactions that have been mined into the Ethereum blockchain",
|
2021-08-13 21:41:25 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/ethereum/eth-diamond-purple.png",
|
2021-08-12 19:23:21 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2023-06-21 14:48:03 +00:00
|
|
|
active=False,
|
2021-08-12 19:23:21 +00:00
|
|
|
),
|
2021-11-14 11:18:52 +00:00
|
|
|
"polygon_blockchain": SubscriptionTypeResourceData(
|
|
|
|
id="polygon_blockchain",
|
|
|
|
name="Polygon transactions",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="polygon",
|
2021-11-14 11:18:52 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Transactions that have been mined into the Polygon blockchain",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/matic-token-inverted-icon.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2023-06-21 14:48:03 +00:00
|
|
|
active=False,
|
2021-11-14 11:18:52 +00:00
|
|
|
),
|
2022-08-10 17:06:47 +00:00
|
|
|
"mumbai_blockchain": SubscriptionTypeResourceData(
|
|
|
|
id="mumbai_blockchain",
|
|
|
|
name="Mumbai transactions",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="mumbai",
|
2022-08-10 17:06:47 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Transactions that have been mined into the Mumbai blockchain",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/matic-token-inverted-icon.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2023-06-21 14:48:03 +00:00
|
|
|
active=False,
|
2022-08-10 17:06:47 +00:00
|
|
|
),
|
2022-05-25 13:47:51 +00:00
|
|
|
"xdai_blockchain": SubscriptionTypeResourceData(
|
|
|
|
id="xdai_blockchain",
|
|
|
|
name="XDai transactions",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="xdai",
|
2022-05-25 13:47:51 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="Gnosis chain transactions subscription.",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/xdai-token-logo.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2023-06-21 14:48:03 +00:00
|
|
|
active=False,
|
2022-05-25 13:47:51 +00:00
|
|
|
),
|
2023-03-06 15:58:25 +00:00
|
|
|
"wyrm_blockchain": SubscriptionTypeResourceData(
|
|
|
|
id="wyrm_blockchain",
|
|
|
|
name="Wyrm transactions",
|
2023-04-20 12:55:22 +00:00
|
|
|
blockchain="wyrm",
|
2023-03-02 12:26:36 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
2023-03-06 15:58:25 +00:00
|
|
|
description="Wyrm chain transactions subscription.",
|
2023-03-07 12:20:26 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/great-wyrm-network-logo.png",
|
2023-03-02 12:26:36 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2023-06-21 14:48:03 +00:00
|
|
|
active=False,
|
2023-03-02 12:26:36 +00:00
|
|
|
),
|
2023-08-30 12:58:50 +00:00
|
|
|
"zksync_era_blockchain": SubscriptionTypeResourceData(
|
|
|
|
id="zksync_era_blockchain",
|
|
|
|
name="zkSync Era transactions",
|
|
|
|
blockchain="zksync_era",
|
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="ZkSync Era chain transactions subscription.",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/zksync-era-token-logo.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=False,
|
|
|
|
),
|
2023-07-13 14:37:42 +00:00
|
|
|
"zksync_era_testnet_blockchain": SubscriptionTypeResourceData(
|
|
|
|
id="zksync_era_testnet_blockchain",
|
|
|
|
name="zkSync Era testnet transactions",
|
|
|
|
blockchain="zksync_era_testnet",
|
|
|
|
choices=["input:address", "tag:erc721"],
|
|
|
|
description="ZkSync Era testnet chain transactions subscription.",
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/zksync-era-testnet-token-logo.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
|
|
|
active=False,
|
|
|
|
),
|
2021-08-12 19:23:21 +00:00
|
|
|
"ethereum_whalewatch": SubscriptionTypeResourceData(
|
|
|
|
id="ethereum_whalewatch",
|
|
|
|
name="Ethereum whale watch",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="ethereum",
|
2021-08-12 19:23:21 +00:00
|
|
|
description="Ethereum accounts that have experienced a lot of recent activity",
|
2021-09-07 12:35:05 +00:00
|
|
|
choices=[],
|
2021-08-13 21:41:25 +00:00
|
|
|
# Icon taken from: https://www.maxpixel.net/Whale-Cetacean-Wildlife-Symbol-Ocean-Sea-Black-99310
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/whalewatch.png",
|
2021-08-12 19:23:21 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2023-06-21 14:48:03 +00:00
|
|
|
active=False,
|
2021-08-12 19:23:21 +00:00
|
|
|
),
|
|
|
|
"ethereum_txpool": SubscriptionTypeResourceData(
|
|
|
|
id="ethereum_txpool",
|
|
|
|
name="Ethereum transaction pool",
|
2023-01-26 15:19:25 +00:00
|
|
|
blockchain="ethereum",
|
2021-08-12 19:23:21 +00:00
|
|
|
description="Transactions that have been submitted into the Ethereum transaction pool but not necessarily mined yet",
|
2021-09-08 17:41:25 +00:00
|
|
|
choices=["input:address", "tag:erc721"],
|
2021-08-13 21:41:25 +00:00
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/ethereum/eth-diamond-rainbow.png",
|
2021-08-12 19:23:21 +00:00
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2023-06-21 14:48:03 +00:00
|
|
|
active=False,
|
|
|
|
),
|
|
|
|
"externaly_owned_account": SubscriptionTypeResourceData(
|
|
|
|
id="externaly_owned_account",
|
|
|
|
name="Externally owned account",
|
2023-06-22 12:28:56 +00:00
|
|
|
blockchain="Any",
|
2023-06-21 14:48:03 +00:00
|
|
|
description="Externally owned account",
|
|
|
|
choices=[],
|
|
|
|
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/ethereum/eth-diamond-rainbow.png",
|
|
|
|
stripe_product_id=None,
|
|
|
|
stripe_price_id=None,
|
2021-08-25 09:38:23 +00:00
|
|
|
active=True,
|
2021-08-12 19:23:21 +00:00
|
|
|
),
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-08-12 18:27:54 +00:00
|
|
|
class ConflictingSubscriptionTypesError(Exception):
|
|
|
|
"""
|
|
|
|
Raised when caller tries to add a resource that conflicts with an existing resource.
|
|
|
|
"""
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class SubscriptionTypeNotFoundError(Exception):
|
|
|
|
"""
|
|
|
|
Raised when a subscription type is expected to exist as a Brood resource but is not found.
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
class UnexpectedError(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
BUGOUT_RESOURCE_TYPE = "subscription_type"
|
|
|
|
|
|
|
|
|
2021-08-12 19:23:21 +00:00
|
|
|
def create_subscription_type(
|
2021-08-12 18:27:54 +00:00
|
|
|
id: str,
|
|
|
|
name: str,
|
|
|
|
description: str,
|
2021-08-13 21:41:25 +00:00
|
|
|
icon_url: str,
|
2021-09-09 12:05:38 +00:00
|
|
|
choices: List[str] = [],
|
2023-06-21 14:48:03 +00:00
|
|
|
blockchain: Optional[str] = None,
|
2021-08-12 18:27:54 +00:00
|
|
|
stripe_product_id: Optional[str] = None,
|
|
|
|
stripe_price_id: Optional[str] = None,
|
|
|
|
active: bool = False,
|
2021-08-12 19:23:21 +00:00
|
|
|
) -> BugoutResource:
|
2021-08-12 18:27:54 +00:00
|
|
|
"""
|
|
|
|
Add a new Moonstream subscription type as a Brood resource.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
- id: Moonstream ID for the subscription type. Examples: "ethereum_blockchain", "ethereum_txpool",
|
|
|
|
"ethereum_whalewatch", etc.
|
|
|
|
- name: Human-friendly name for the subscription type, which can be displayed to users.
|
|
|
|
- description: Detailed description of the subscription type for users who would like more
|
|
|
|
information.
|
2021-08-13 22:17:18 +00:00
|
|
|
- icon_url: URL to the icon for this subscription type
|
2021-08-12 18:27:54 +00:00
|
|
|
- stripe_product_id: Optional product ID from Stripe account dashboard.
|
|
|
|
- stripe_price_id: Optional price ID from Stripe account dashboard.
|
|
|
|
- active: Set to True if you would like the subscription type to immediately be available for
|
|
|
|
subscriptions. If you set this to False (which is the default), users will not be able to create
|
|
|
|
subscriptions of this type until you later on set to true.
|
|
|
|
"""
|
|
|
|
params = {"type": BUGOUT_RESOURCE_TYPE, "id": id}
|
|
|
|
|
|
|
|
response: BugoutResources = bc.list_resources(
|
2021-08-12 18:38:15 +00:00
|
|
|
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
|
|
|
params=params,
|
|
|
|
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
|
2021-08-12 18:27:54 +00:00
|
|
|
)
|
|
|
|
if response.resources:
|
|
|
|
raise ConflictingSubscriptionTypesError(
|
|
|
|
f"There is already a subscription_type with id: {id}"
|
|
|
|
)
|
|
|
|
|
|
|
|
subscription_data = {
|
|
|
|
"type": BUGOUT_RESOURCE_TYPE,
|
|
|
|
"id": id,
|
|
|
|
"name": name,
|
|
|
|
"description": description,
|
2021-09-07 16:42:31 +00:00
|
|
|
"choices": choices,
|
2023-06-22 12:10:50 +00:00
|
|
|
"blockchain": blockchain,
|
2021-08-13 21:41:25 +00:00
|
|
|
"icon_url": icon_url,
|
2021-08-12 18:27:54 +00:00
|
|
|
"stripe_product_id": stripe_product_id,
|
|
|
|
"stripe_price_id": stripe_price_id,
|
|
|
|
"active": active,
|
|
|
|
}
|
|
|
|
|
|
|
|
resource = bc.create_resource(
|
|
|
|
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
|
|
|
application_id=MOONSTREAM_APPLICATION_ID,
|
|
|
|
resource_data=subscription_data,
|
|
|
|
)
|
|
|
|
|
2021-08-12 19:23:21 +00:00
|
|
|
return resource
|
2021-08-12 18:27:54 +00:00
|
|
|
|
|
|
|
|
2021-08-12 19:23:21 +00:00
|
|
|
def cli_create_subscription_type(args: argparse.Namespace) -> None:
|
2021-08-12 18:27:54 +00:00
|
|
|
"""
|
|
|
|
Handler for "mnstr subtypes create".
|
|
|
|
"""
|
2021-08-12 19:23:21 +00:00
|
|
|
result = create_subscription_type(
|
2021-08-12 18:27:54 +00:00
|
|
|
args.id,
|
|
|
|
args.name,
|
|
|
|
args.description,
|
2023-06-21 14:48:03 +00:00
|
|
|
args.blockchain,
|
2021-08-13 21:41:25 +00:00
|
|
|
args.icon,
|
2021-09-08 15:43:34 +00:00
|
|
|
args.choices,
|
2021-08-12 18:27:54 +00:00
|
|
|
args.stripe_product_id,
|
|
|
|
args.stripe_price_id,
|
|
|
|
args.active,
|
|
|
|
)
|
2021-08-12 19:23:21 +00:00
|
|
|
print(result.json())
|
2021-08-12 18:27:54 +00:00
|
|
|
|
|
|
|
|
2021-08-12 23:05:42 +00:00
|
|
|
def list_subscription_types(active_only: bool = False) -> BugoutResources:
|
2021-08-12 18:27:54 +00:00
|
|
|
"""
|
|
|
|
Lists all subscription types registered as Brood resources for this Moonstream application.
|
2021-08-12 23:05:42 +00:00
|
|
|
|
|
|
|
Args:
|
|
|
|
- active_only: Set this to true if you only want to list active subscription types. By default,
|
|
|
|
all subscription types are listed, be they active or inactive.
|
2021-08-12 18:27:54 +00:00
|
|
|
"""
|
|
|
|
response = bc.list_resources(
|
2021-08-12 18:38:15 +00:00
|
|
|
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
|
|
|
params={"type": BUGOUT_RESOURCE_TYPE},
|
|
|
|
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
|
2021-08-12 18:27:54 +00:00
|
|
|
)
|
2021-08-12 23:05:42 +00:00
|
|
|
|
|
|
|
# TODO(kompotkot): Currently, we cannot filter using non-string fields in Brood resources. This means
|
|
|
|
# that we have to implement the active_only filter in this API instead of just setting a query parameter
|
|
|
|
# in the Brood API call. This should be fixed.
|
|
|
|
if not active_only:
|
|
|
|
return response
|
|
|
|
|
|
|
|
active_resources = [
|
|
|
|
resource for resource in response.resources if resource.resource_data["active"]
|
|
|
|
]
|
|
|
|
return BugoutResources(resources=active_resources)
|
2021-08-12 18:27:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
def cli_list_subscription_types(args: argparse.Namespace) -> None:
|
|
|
|
"""
|
|
|
|
Handler for "mnstr subtypes list".
|
|
|
|
"""
|
2021-08-12 23:05:42 +00:00
|
|
|
results = list_subscription_types(args.active)
|
2021-08-12 19:23:21 +00:00
|
|
|
print(results.json())
|
2021-08-12 18:27:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_subscription_type(id: str) -> Optional[BugoutResource]:
|
|
|
|
"""
|
|
|
|
Retrieves the resource representing the subscription type with the given ID.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
- id: Moonstream ID for the subscription type (not the Brood resource ID).
|
|
|
|
Examples - "ethereum_blockchain", "ethereum_whalewatch", etc.
|
|
|
|
|
|
|
|
Returns: None if there is no subscription type with that ID. Otherwise, returns the full
|
|
|
|
Brood resource. To access the subscription type itself, use the "resource_data" member of the
|
|
|
|
return value. If more than one subscription type is found with the given ID, raises a
|
|
|
|
ConflictingSubscriptionTypesError.
|
|
|
|
"""
|
|
|
|
response = bc.list_resources(
|
|
|
|
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
|
|
|
params={"type": BUGOUT_RESOURCE_TYPE, "id": id},
|
2021-08-12 18:38:15 +00:00
|
|
|
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
|
2021-08-12 18:27:54 +00:00
|
|
|
)
|
|
|
|
resources = response.resources
|
|
|
|
|
|
|
|
if not resources:
|
|
|
|
return None
|
|
|
|
if len(resources) > 1:
|
|
|
|
raise ConflictingSubscriptionTypesError(
|
|
|
|
f"More than one resource with the given ID:\n{json.dumps(resources, indent=2)}"
|
|
|
|
)
|
|
|
|
return resources[0]
|
|
|
|
|
|
|
|
|
|
|
|
def cli_get_subscription_type(args: argparse.Namespace) -> None:
|
|
|
|
"""
|
|
|
|
Handler for "mnstr subtypes get".
|
|
|
|
"""
|
|
|
|
resource = get_subscription_type(args.id)
|
|
|
|
if resource is None:
|
|
|
|
print(f"Could not find resource with ID: {id}")
|
|
|
|
else:
|
|
|
|
print(resource.json())
|
|
|
|
|
|
|
|
|
|
|
|
def update_subscription_type(
|
|
|
|
id: str,
|
|
|
|
name: Optional[str] = None,
|
|
|
|
description: Optional[str] = None,
|
2021-09-07 12:35:05 +00:00
|
|
|
choices: Optional[List[str]] = None,
|
2023-06-21 14:48:03 +00:00
|
|
|
blockchain: Optional[str] = None,
|
2021-08-13 21:41:25 +00:00
|
|
|
icon_url: Optional[str] = None,
|
2021-08-12 18:27:54 +00:00
|
|
|
stripe_product_id: Optional[str] = None,
|
|
|
|
stripe_price_id: Optional[str] = None,
|
|
|
|
active: Optional[bool] = None,
|
2021-08-12 19:23:21 +00:00
|
|
|
) -> BugoutResource:
|
2021-08-12 18:27:54 +00:00
|
|
|
"""
|
|
|
|
Update a Moonstream subscription type using the Brood Resources API.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
- id: Moonstream ID for the subscription type. Examples: "ethereum_blockchain", "ethereum_txpool",
|
|
|
|
"ethereum_whalewatch", etc.
|
|
|
|
- name: Human-friendly name for the subscription type, which can be displayed to users.
|
|
|
|
- description: Detailed description of the subscription type for users who would like more
|
|
|
|
information.
|
2021-08-13 22:17:18 +00:00
|
|
|
- icon_url: URL to the icon for this subscription type
|
2021-08-12 18:27:54 +00:00
|
|
|
- stripe_product_id: Optional product ID from Stripe account dashboard.
|
|
|
|
- stripe_price_id: Optional price ID from Stripe account dashboard.
|
|
|
|
- active: Set to True if you would like the subscription type to immediately be available for
|
|
|
|
subscriptions. If you set this to False (which is the default), users will not be able to create
|
|
|
|
subscriptions of this type until you later on set to true.
|
|
|
|
"""
|
|
|
|
|
|
|
|
resource = get_subscription_type(id)
|
|
|
|
if resource is None:
|
|
|
|
raise SubscriptionTypeNotFoundError(
|
|
|
|
f"Could not find subscription type with ID: {id}."
|
|
|
|
)
|
|
|
|
|
|
|
|
brood_resource_id = resource.id
|
|
|
|
updated_resource_data = resource.resource_data
|
|
|
|
if name is not None:
|
|
|
|
updated_resource_data["name"] = name
|
|
|
|
if description is not None:
|
|
|
|
updated_resource_data["description"] = description
|
2021-09-07 12:35:05 +00:00
|
|
|
if choices is not None:
|
|
|
|
updated_resource_data["choices"] = choices
|
2023-06-22 12:10:50 +00:00
|
|
|
if blockchain is not None:
|
|
|
|
updated_resource_data["blockchain"] = blockchain
|
2021-08-13 21:41:25 +00:00
|
|
|
if icon_url is not None:
|
|
|
|
updated_resource_data["icon_url"] = icon_url
|
2021-08-12 18:27:54 +00:00
|
|
|
if stripe_product_id is not None:
|
|
|
|
updated_resource_data["stripe_product_id"] = stripe_product_id
|
|
|
|
if stripe_price_id is not None:
|
|
|
|
updated_resource_data["stripe_price_id"] = stripe_price_id
|
|
|
|
if active is not None:
|
|
|
|
updated_resource_data["active"] = active
|
2021-08-13 21:41:25 +00:00
|
|
|
|
2021-08-13 15:09:29 +00:00
|
|
|
# TODO(zomglings): This was written with an outdated bugout-python client.
|
|
|
|
# New client has an update_resource method which is what we should be using
|
|
|
|
# here.
|
2021-08-12 18:27:54 +00:00
|
|
|
|
2021-08-12 18:38:15 +00:00
|
|
|
try:
|
2021-09-07 15:56:12 +00:00
|
|
|
new_resource = bc.update_resource(
|
2021-08-12 18:38:15 +00:00
|
|
|
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
|
|
|
resource_id=brood_resource_id,
|
2021-09-07 15:56:12 +00:00
|
|
|
resource_data={"update": updated_resource_data},
|
2021-08-12 18:38:15 +00:00
|
|
|
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
|
|
|
|
)
|
2021-09-07 15:56:12 +00:00
|
|
|
|
2021-08-12 18:38:15 +00:00
|
|
|
except Exception as e:
|
|
|
|
raise ConflictingSubscriptionTypesError(
|
|
|
|
f"Unable to delete old subscription type with ID: {id}. Error:\n{repr(e)}"
|
|
|
|
)
|
|
|
|
|
2021-08-12 19:23:21 +00:00
|
|
|
return new_resource
|
2021-08-12 18:27:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
def cli_update_subscription_type(args: argparse.Namespace) -> None:
|
|
|
|
"""
|
|
|
|
Handler for "mnstr subtypes update".
|
|
|
|
"""
|
|
|
|
result = update_subscription_type(
|
|
|
|
args.id,
|
|
|
|
args.name,
|
|
|
|
args.description,
|
2021-09-07 12:35:05 +00:00
|
|
|
args.choices,
|
2023-06-21 14:48:03 +00:00
|
|
|
args.blockchain,
|
2021-08-13 21:41:25 +00:00
|
|
|
args.icon,
|
2021-08-12 18:27:54 +00:00
|
|
|
args.stripe_product_id,
|
|
|
|
args.stripe_price_id,
|
|
|
|
args.active,
|
|
|
|
)
|
2021-08-12 19:23:21 +00:00
|
|
|
print(result.json())
|
2021-08-12 18:38:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
def delete_subscription_type(id: str) -> Optional[BugoutResource]:
|
|
|
|
"""
|
|
|
|
Deletes the subscription type resource with the given ID.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
- id: Moonstream ID of the subscription type you would like to delete. Examples - "ethereum_blockchain",
|
|
|
|
"ethereum_whalewatch", etc.
|
|
|
|
|
|
|
|
Returns: The BugoutResource that was deleted. If no such resource existed in the first place, returns
|
|
|
|
None. If multiple resources existed with the given Moonstream ID, raises a ConflictingSubscriptionTypesError
|
|
|
|
and does not delete anything!
|
|
|
|
"""
|
2021-08-12 21:40:47 +00:00
|
|
|
# ConflictingSubscriptionTypesError raised here if there are multiple resources with the given id.
|
2021-08-12 18:38:15 +00:00
|
|
|
resource = get_subscription_type(id)
|
|
|
|
if resource is None:
|
|
|
|
return None
|
|
|
|
|
|
|
|
resource = bc.delete_resource(
|
|
|
|
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
|
|
|
resource_id=resource.id,
|
|
|
|
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
|
|
|
|
)
|
|
|
|
|
|
|
|
return resource
|
|
|
|
|
|
|
|
|
|
|
|
def cli_delete_subscription_type(args: argparse.Namespace) -> None:
|
|
|
|
"""
|
|
|
|
Handler for "mnstr subtypes delete".
|
|
|
|
"""
|
|
|
|
result = delete_subscription_type(args.id)
|
2021-08-12 19:23:21 +00:00
|
|
|
if result is None:
|
|
|
|
print(f"Could not find resource with ID: {id}")
|
|
|
|
else:
|
|
|
|
print(result.json())
|
|
|
|
|
|
|
|
|
|
|
|
def ensure_canonical_subscription_types() -> BugoutResources:
|
|
|
|
"""
|
|
|
|
Ensures that the connected Brood API has at least the canonical subscription types. If any of the
|
|
|
|
canonical subscription types does not exist as a Brood resource, this API creates the corresponding
|
|
|
|
resource. If any of the canonical subscription types exists as a Brood resource but has been modified,
|
|
|
|
this method does not change it on the server.
|
|
|
|
|
|
|
|
Args: None
|
|
|
|
|
|
|
|
Returns: A list of the resources representing the canonical subscription types as they exist
|
|
|
|
on the connected Brood API.
|
|
|
|
"""
|
|
|
|
existing_canonical_subscription_types: Dict[str, BugoutResource] = {}
|
|
|
|
for id, canonical_subscription_type in CANONICAL_SUBSCRIPTION_TYPES.items():
|
|
|
|
resource = get_subscription_type(canonical_subscription_type.id)
|
|
|
|
if resource is not None:
|
|
|
|
existing_canonical_subscription_types[id] = resource
|
|
|
|
|
|
|
|
for id in CANONICAL_SUBSCRIPTION_TYPES.keys():
|
|
|
|
if existing_canonical_subscription_types.get(id) is None:
|
|
|
|
canonical_subscription_type = CANONICAL_SUBSCRIPTION_TYPES[id]
|
|
|
|
resource = create_subscription_type(
|
|
|
|
id,
|
|
|
|
canonical_subscription_type.name,
|
|
|
|
canonical_subscription_type.description,
|
2021-08-13 21:41:25 +00:00
|
|
|
canonical_subscription_type.icon_url,
|
2021-09-08 15:43:34 +00:00
|
|
|
canonical_subscription_type.choices,
|
2023-06-21 14:48:03 +00:00
|
|
|
canonical_subscription_type.blockchain,
|
2021-08-12 19:23:21 +00:00
|
|
|
canonical_subscription_type.stripe_product_id,
|
|
|
|
canonical_subscription_type.stripe_price_id,
|
|
|
|
canonical_subscription_type.active,
|
|
|
|
)
|
|
|
|
existing_canonical_subscription_types[id] = resource
|
2021-09-07 16:42:31 +00:00
|
|
|
else:
|
|
|
|
canonical_subscription_type = CANONICAL_SUBSCRIPTION_TYPES[id]
|
|
|
|
resource = update_subscription_type(
|
|
|
|
id,
|
|
|
|
canonical_subscription_type.name,
|
|
|
|
canonical_subscription_type.description,
|
|
|
|
canonical_subscription_type.choices,
|
2023-06-21 14:48:03 +00:00
|
|
|
canonical_subscription_type.blockchain,
|
2021-09-07 16:42:31 +00:00
|
|
|
canonical_subscription_type.icon_url,
|
|
|
|
canonical_subscription_type.stripe_product_id,
|
|
|
|
canonical_subscription_type.stripe_price_id,
|
|
|
|
canonical_subscription_type.active,
|
|
|
|
)
|
|
|
|
existing_canonical_subscription_types[id] = resource
|
2021-08-12 19:23:21 +00:00
|
|
|
|
|
|
|
return BugoutResources(
|
|
|
|
resources=list(existing_canonical_subscription_types.values())
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def cli_ensure_canonical_subscription_types(args: argparse.Namespace) -> None:
|
2021-08-12 21:00:54 +00:00
|
|
|
"""
|
|
|
|
Handler for "mnstr subtypes ensure-canonical
|
|
|
|
"""
|
2021-08-12 19:23:21 +00:00
|
|
|
resources = ensure_canonical_subscription_types()
|
|
|
|
print(resources.json())
|