Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@motorina0
Copy link
Collaborator

@motorina0 motorina0 commented May 17, 2024

Summary

The functionality in this PR allows the administrators of LNbits instances to ask for payment when a regular user wants to enable an extension. The payment will go to a wallet specified by the admin.
Once a user pays for an extension, that extension will be accessible for that user no matter if it is upgraded or the user enables/disables multiple times.

Check this comment before merging: #2516 (comment)

Screenshots

  • set price for extension
    • image
  • pay for extension
    • image
pay_to_enable.mov

Depends on: #2516

  • do not request payment for admins
  • do not request payment to re-enable
  • move activate/deactivate and enable/disable from views to api
  • jmeter test for all of the above functionality

@arcbtc
Copy link
Member

arcbtc commented May 17, 2024

not only will we now have an inncentive for developers to make extensions they can sell, we also have a massive incentive for people just to run LNbits and attract users. This is really amazing

@codecov
Copy link

codecov bot commented May 17, 2024

Codecov Report

Attention: Patch coverage is 31.01604% with 129 lines in your changes are missing coverage. Please review.

Project coverage is 61.38%. Comparing base (7c68a02) to head (cc64a53).

Files Patch % Lines
lnbits/core/views/extension_api.py 14.28% 102 Missing ⚠️
lnbits/core/crud.py 45.00% 11 Missing ⚠️
lnbits/extension_manager.py 70.00% 9 Missing ⚠️
lnbits/core/helpers.py 0.00% 3 Missing ⚠️
lnbits/core/views/generic.py 57.14% 3 Missing ⚠️
lnbits/exceptions.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #2516      +/-   ##
==========================================
- Coverage   61.98%   61.38%   -0.61%     
==========================================
  Files          69       69              
  Lines        9729     9865     +136     
==========================================
+ Hits         6031     6056      +25     
- Misses       3698     3809     +111     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@motorina0 motorina0 force-pushed the pay_to_enable_extension branch 2 times, most recently from 5f1196a to 022296e Compare May 24, 2024 06:55

async def send_payment_notification(wallet: Wallet, payment: Payment):
await websocket_updater(
wallet.id,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valid fix unrelated to this PR

stop_fn_name = next((fn for fn in stop_fns if hasattr(old_module, fn)), None)
assert stop_fn_name, "No stop function found for '{ext.module_name}'"

await getattr(old_module, stop_fn_name)()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valid fix unrelated to this PR

@motorina0 motorina0 force-pushed the pay_to_enable_extension branch from 52a7605 to 6d3ab34 Compare May 27, 2024 10:45
) from exc


async def toggle_extension(extension_to_enable, extension_to_disable, user_id):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logic is moved to: /api/v1/extension/{ext_id}/enable and /api/v1/extension/{ext_id}/disable

Comment on lines -114 to -133
ext_id = activate or deactivate
all_extensions = get_valid_extensions()
ext = next((e for e in all_extensions if e.code == ext_id), None)
if ext_id and user.admin:
if deactivate:
settings.lnbits_deactivated_extensions.add(deactivate)
elif activate:
# if extension never loaded (was deactivated on server startup)
if ext_id not in sys.modules.keys():
# run extension start-up routine
core_app_extra.register_new_ext_routes(ext)

settings.lnbits_deactivated_extensions.remove(activate)

await update_installed_extension_state(
ext_id=ext_id, active=activate is not None
)

all_ext_ids = [ext.code for ext in all_extensions]
inactive_extensions = await get_inactive_extensions()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logic is moved to: /api/v1/extension/{ext_id}/activate and /api/v1/extension/{ext_id}/deactivate

Comment on lines -53 to -81


# check GET /extensions: enable extension
# TODO: test fails because of removing lnurlp extension
# @pytest.mark.asyncio
# async def test_get_extensions_enable(client, to_user):
# response = await client.get(
# "extensions", params={"usr": to_user.id, "enable": "lnurlp"}
# )
# assert response.status_code == 200, f"{response.url} {response.status_code}"


# check GET /extensions: enable and disable extensions, expect code 400 bad request
# @pytest.mark.asyncio
# async def test_get_extensions_enable_and_disable(client, to_user):
# response = await client.get(
# "extensions",
# params={"usr": to_user.id, "enable": "lnurlp", "disable": "lnurlp"},
# )
# assert response.status_code == 400, f"{response.url} {response.status_code}"


# check GET /extensions: enable nonexistent extension, expect code 400 bad request
@pytest.mark.asyncio
async def test_get_extensions_enable_nonexistent_extension(client, to_user):
response = await client.get(
"extensions", params={"usr": to_user.id, "enable": "12341234"}
)
assert response.status_code == 400, f"{response.url} {response.status_code}"
Copy link
Collaborator Author

@motorina0 motorina0 May 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run: |
git clone https://github.com/lnbits/lnbits-extensions
cd lnbits-extensions
git checkout pay_to_enable_extension_upgrades
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before merging into dev:

@motorina0 motorina0 marked this pull request as ready for review May 27, 2024 12:01
@arcbtc arcbtc merged commit d72cf40 into dev May 28, 2024
@arcbtc arcbtc deleted the pay_to_enable_extension branch May 28, 2024 11:07
motorina0 added a commit that referenced this pull request Jul 10, 2024
* feat: add payment tab

* feat: add buttons

* feat: persist `pay to enable` changes

* fix: do not disable extension on upgrade

* fix: show releases tab first

* feat: extract `enableExtension` logic

* refactor: rename routes

* feat: show dialog for paying extension

* feat: create invoice to enable

* refactor: extract enable/disable extension logic

* feat: add extra info to UserExtensions

* feat: check payment for extension enable

* fix: parsing

* feat: admins must not pay

* fix: code checks

* fix: test

* refactor: extract extension activate/deactivate to the `api` side

* feat: add `get_user_extensions `

* feat: return explicit `requiresPayment`

* feat: add `isPaymentRequired` to extension list

* fix: `paid_to_enable` status

* fix: ui layout

* feat: show QR Code

* feat: wait for invoice to be paid

* test: removed deprecated test and dead code

* feat: add re-check button

* refactor: rename paths for endpoints

* feat: i18n

* feat: add `{"success": True}`

* test: fix listener

* fix: rebase errors

* chore: update bundle

* fix: return error status code for the HTML error pages

* fix: active extension loading from file system

* chore: temp commit

* fix: premature optimisation

* chore: make check

* refactor: remove extracted logic

* chore: code format

* fix: enable by default after install

* fix: use `discard` instead of `remove` for `set`

* chore: code format

* fix: better error code

* fix: check for stop function before invoking

* feat: check if the wallet belongs to the admin user

* refactor: return 402 Requires Payment

* chore: more typing

* chore: temp checkout different branch for tests

* fix: too much typing

* fix: remove try-except

* fix: typo

* fix: manual format

* fix: merge issue

* remove this line

---------

Co-authored-by: dni ⚡ <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants