Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Switch to 3cities #2

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
943fc59
Add .ignore
ryanberckmans May 6, 2024
9a705ad
Add .nvmrc
ryanberckmans May 6, 2024
ab9bdb6
Add 'make shell'
ryanberckmans May 6, 2024
294b5fb
Add stub 3cities grpc client
ryanberckmans May 6, 2024
df4325b
Begin switching payment engine to 3cities
ryanberckmans May 6, 2024
83fa82c
Close 3cities iframe after paying
ryanberckmans May 7, 2024
da65f73
Use latest 3cities API params
ryanberckmans May 16, 2024
cd8b8a0
Increase 3cities pop-up width to min desktop width
ryanberckmans May 16, 2024
9c9ddbe
Use 3cities.xyx instead of localhost
ryanberckmans May 16, 2024
611df99
Allow writing to clipboard in 3cities iframe
ryanberckmans May 16, 2024
3c01129
fixup
ryanberckmans May 16, 2024
758103f
Support ETH payments using 3cities
ryanberckmans Jun 16, 2024
5aa4c96
Bump pretix to >=2024.2, python to >=3.9 <4
ryanberckmans Jun 16, 2024
a3c9bf8
do not downgrade pretix becuase of this
kvbik Jun 27, 2024
d3acfed
Merge pull request #3 from kvbik/patch-1
ryanberckmans Jun 29, 2024
3464a85
Upgrade to pretix 2024.6.0
ryanberckmans Jun 29, 2024
1a5c2dc
Update 3cities url baked into js
ryanberckmans Jun 29, 2024
f13674a
Temporarily disable verify_payment in confirm_payments
ryanberckmans Jun 30, 2024
b27590c
fixup
ryanberckmans Jun 30, 2024
fa6ba3d
Prepare for production
ryanberckmans Jul 8, 2024
1c165c9
Allow pretix 2024.2
ryanberckmans Jul 8, 2024
96a3d6b
Allow long SignedMessage.signature and fix save bug
ryanberckmans Jul 8, 2024
92e578e
Temp debug
ryanberckmans Jul 8, 2024
b92a08b
Source csrf cookie from __Host- variant, too
ryanberckmans Jul 8, 2024
762739d
Polish for production
ryanberckmans Jul 9, 2024
6b94db6
Temporarily restrict allowed tokens to ETH and DAI
ryanberckmans Jul 9, 2024
aa67d30
Bump plugin version to 4.0.0
ryanberckmans Jul 9, 2024
213f90f
Disable Polygon zkEVM
ryanberckmans Jul 9, 2024
69a4d0f
Add queuePromise.js
ryanberckmans Jul 10, 2024
980b16c
Revamp transaction details submission & monitoring
ryanberckmans Jul 10, 2024
851523b
Warn more to not close pop-up or page during payment
ryanberckmans Jul 11, 2024
b937cf3
Add 3cities environment plugin setting
ryanberckmans Jul 12, 2024
e9d822f
Call grpc verifier service on confirm_payments
ryanberckmans Jul 13, 2024
325f74d
fixup
ryanberckmans Jul 13, 2024
6060574
Prioritize env var over mkcert for ca root path
ryanberckmans Jul 13, 2024
3cf9a71
Support TurnOn/OffKeepIframeOpen iframe msgs
ryanberckmans Jul 16, 2024
c124ed9
option for the command to run only one event
kvbik Jul 16, 2024
62cd4c7
Use 3cities's hideReceiverAddress
ryanberckmans Jul 25, 2024
124e1ba
Add SignedMessage.verification_failed_permanently/verification_explan…
ryanberckmans Jul 26, 2024
095ef36
fixup
ryanberckmans Jul 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# an ignore file for ripgrep, a grep alternative https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#automatic-filtering
web3modal-dist
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts/iron
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ devserver:
devmigrate:
python -mpretix migrate

shell:
python -mpretix shell

.PHONY: all localecompile localegen
132 changes: 46 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,8 @@
# Pretix Ethereum Payment Provider

## **Important disclaimers**

**!! Smart contract wallet payments are NOT supported (except Safe) and users will be told so (and be unable to pay) when they connect with one. A rare edge case exists with counterfactual wallets that will prevent the plugin from detecting if the connected wallet is a smart contract - if a user manages to pay this way, their payment will not confirm automatically (note: an organizer can still manually confirm payments in this case)**

**!! This plugin is no longer actively being worked on. PRs to finish smart contract wallet support are welcome (further details below). As of early 2024, The Devcon team is working with third party payment providers to improve payment UX and add smart contract wallet support, and may publish this work under a different plugin some time in the future.**

## What is this

This is a plugin for [pretix](https://github.com/pretix/pretix). This plugin
supports both Ethereum and DAI.

## History

It started with [ligi](https://ligi) suggesting [pretix for Ethereum
Magicians](https://ethereum-magicians.org/t/charging-for-tickets-participant-numbers-event-ticketing-for-council-of-paris-2019/2321/2).

Then it was used for Ethereum Magicians in Paris (shout out to
[boris](https://github.com/bmann) for making this possible) - but accepting ETH
or DAI was a fully manual process there.

Afterwards boris [put up some funds for a gitcoin
bounty](https://github.com/spadebuilders/community/issues/30) to make a plugin
that automates this process. And [nanexcool](https://github.com/nanexcool)
increased the funds and added the requirement for DAI.

The initial version was developed by [vic-en](https://github.com/vic-en) but he
vanished from the project after cashing in the bounty money and left the plugin
in a non-working state.

Then the idea came up to use this plugin for DevCon5 and the plugin was forked
to this repo and [ligi](https://ligi.de), [david
sanders](https://github.com/davesque), [piper
meriam](https://github.com/pipermerriam), [rami](https://github.com/raphaelm),
[Pedro Gomes](https://github.com/pedrouid), and [Jamie
Pitts](https://github.com/jpitts) brought it to a state where it is usable for
DevCon5 (still a lot of work to be done to make this a good plugin). Currently,
it is semi-automatic. But it now has ERC-681 and Web3Modal
support. If you want to dig a bit into the problems that emerged short before
the launch you can have a look at [this
issue](https://github.com/esPass/pretix-eth-payment-plugin/pull/49)

For DEVcon6 the plugin was extended with some more features like [Layer2 support by Rahul](https://github.com/rahul-kothari). Layer2 will play a significant [role in Ethereum](https://ethereum-magicians.org/t/a-rollup-centric-ethereum-roadmap/4698). Unfortunately DEVcon6 was delayed due to covid - but we where able to use and this way test via the [LisCon](https://liscon.org) ticket sale. As far as we know this was the first event ever offering a Layer2 payment option.
In the process tooling like [Web3Modal](https://github.com/Web3Modal/web3modal/) / [Checkout](https://github.com/Web3Modal/web3modal-checkout) that we depend on was improved.

For Devconnect IST an effort was made to improve the plugin in a variety of ways: WalletConnect support, single receiver mode (accept payments using just one wallet), more networks, automatic ETH rate fetching, improved UI and messaging, and smart contract wallet support. All of these features made it into this version of the plugin, except for smart contract wallet support - issues processing transactions stemming from sc wallets meant that we ultimately had to turn away sc wallet payments altogether.

If you are a dev and want to "finish" the plugin by adding smart contract wallet support, the main thing missing is the ability to verify the sender+receiver addresses and the amount sent given a tx hash stemming from a smart contract wallet. Smart contract transaction receipts aren't easy to process because the "to" and "value" field are not useful - to get the actual receiver wallet and the amount sent, more complex processing is needed (presumably by looking at the transaction logs - but it has to be generic, because each sc wallet has different internals). ERC1271 support is already added, so it really is just about building this "verifier".

### Recently added features

* A payment confirmation management command was added that confirms pending
payments based on the address assigned to them during checkout. See the
`confirm_payments` section below for details.
* "Single receiver" mode (accept all payments using just one wallet)
* WalletConnect support
* Automatic ETH rate fetching
* More L2s added
* Updated user-facing UI and error messaging
* ERC1271 support (note: smart contract payments not yet fully supported - the confirm payment cannot handle sc wallet payments, see warning above for details)
This is an Ethereum payment plugin for [pretix](https://github.com/pretix/pretix). This plugin sends and verifies the payment using [3cities](https://3cities.xyz/).

## Development setup

Expand All @@ -73,42 +17,27 @@ If you are a dev and want to "finish" the plugin by adding smart contract wallet
1. Enter "Admin mode" by clicking the "Admin mode" text in the upper-right
corner of the admin interface to create a test organization and event.
1. Follow instructions in [Event Setup Instructions](#event-setup-instructions)
1. If you need to update web3modal/walletconnect related code, this happens in [the web3modal folder](pretix_eth/web3modal/README.md) - check the README there.
1. If you need to update clientside js code, this happens in [the web3modal folder](pretix_eth/web3modal/README.md) - check the README there.

## Event Setup Instructions
1. Under the event, go to Settings -> Plugins -> Payment Providers -> click on Enable under "Pretix Ethereum Payment Provider"
2. Next, under Settings, go to Payments -> "ETH or DAI" -> Settings -> click on "enable payment method".
2. Next, under Settings, go to Payments -> "Pay on Ethereum" -> Settings -> click on "enable payment method".
3. Next, scroll down and set the values for the following:
- "TOKEN_RATE" - This is a JSON e.g.
```
{"ETH_RATE": 4000, "DAI_RATE": 1}
```
i.e. `KEY` = `<CRYPTO_SMBOL>_RATE` and `VALUE` = value of 1 unit in your fiat currency e.g. USD, EUR etc. For USD, above example says 1 ETH = 4000$. If EUR was chosen, then this says 1 ETH = 4000EUR.

Note that the Ethereum rate will automatically reflect the current market price (regardless of which ETH_RATE you put in the config) - the ETH_RATE you define here is a fallback in the unlikely scenario that the plugin price feeds are down. The ETH_RATE will ONLY automatically reflect the current market price when Event Currency is set to either USD or EUR. If you set your event currency to ANYTHING ELSE the ETH rate will not automatically reflect its market price - it must then be manually input & updated regularly.
- Select the networks you want under the "Networks" option - Choose from Ethereum Mainnet, Optimism, Arbitrum and their testnets.
- "NETWORK_RPC_URLS" - This is a JSON e.g.
```
{
"L1_RPC_URL": "https://mainnet.infura.io/v3/somekeyhere",
"Rinkeby_RPC_URL": "...",
"RinkebyArbitrum_RPC_URL": "..."
}
```
i.e. `KEY` = `<Network ID>_RPC_URL` and `VALUE` = RPC URL. Network IDs can be found [in tokens.py](pretix_eth/network/tokens.py)
- "Payment receiver address" - Ethereum address at which all payments will be sent to
- "WalletConnect project ID" - WalletConnect requires a project id - you can generate one on https://walletconnect.com/

You can now play with the event by clicking on the "Go to Shop" button at the top left (next to the event name)

## 3cities setup

### 3cities payment client
TODO

### Run payment verifier gRPC service
TODO

## Automatic payment confirmation with the `confirm_payments` command

This plugin includes a [django management
command](https://docs.djangoproject.com/en/2.2/howto/custom-management-commands/#module-django.core.management)
that can be used to automatically confirm orders from the Ethereum address
associated with each order across all events. By default, this command will perform a dry run
which only displays payment records that would be modified and why but without
actually modifying them.
This plugin includes a [django management command](https://docs.djangoproject.com/en/2.2/howto/custom-management-commands/#module-django.core.management) that can be used to automatically confirm orders from the Ethereum address associated with each order across all events. By default, this command will perform a dry run which only displays payment records that would be modified and why but without actually modifying them.

Here's an example invocation of this command:
```bash
Expand All @@ -128,8 +57,39 @@ command may be invoked with `--help`:
python -mpretix confirm_payments --help
```

## License
## History

It started with [ligi](https://ligi) suggesting [pretix for Ethereum
Magicians](https://ethereum-magicians.org/t/charging-for-tickets-participant-numbers-event-ticketing-for-council-of-paris-2019/2321/2).

Then it was used for Ethereum Magicians in Paris (shout out to
[boris](https://github.com/bmann) for making this possible) - but accepting ETH
or DAI was a fully manual process there.

Afterwards boris [put up some funds for a gitcoin
bounty](https://github.com/spadebuilders/community/issues/30) to make a plugin
that automates this process. And [nanexcool](https://github.com/nanexcool)
increased the funds and added the requirement for DAI.

The initial version was developed by [vic-en](https://github.com/vic-en) but he
vanished from the project after cashing in the bounty money and left the plugin
in a non-working state.

Copyright 2019 Victor (https://github.com/vic-en)
Then the idea came up to use this plugin for DevCon5 and the plugin was forked
to this repo and [ligi](https://ligi.de), [david
sanders](https://github.com/davesque), [piper
meriam](https://github.com/pipermerriam), [rami](https://github.com/raphaelm),
[Pedro Gomes](https://github.com/pedrouid), and [Jamie
Pitts](https://github.com/jpitts) brought it to a state where it is usable for
DevCon5 (still a lot of work to be done to make this a good plugin). Currently,
it is semi-automatic. But it now has ERC-681 and Web3Modal
support. If you want to dig a bit into the problems that emerged short before
the launch you can have a look at [this
issue](https://github.com/esPass/pretix-eth-payment-plugin/pull/49)

For DEVcon6 the plugin was extended with some more features like [Layer2 support by Rahul](https://github.com/rahul-kothari). Layer2 will play a significant [role in Ethereum](https://ethereum-magicians.org/t/a-rollup-centric-ethereum-roadmap/4698). Unfortunately DEVcon6 was delayed due to covid - but we where able to use and this way test via the [LisCon](https://liscon.org) ticket sale. As far as we know this was the first event ever offering a Layer2 payment option.
In the process tooling like [Web3Modal](https://github.com/Web3Modal/web3modal/) / [Checkout](https://github.com/Web3Modal/web3modal-checkout) that we depend on was improved.

For Devconnect IST an effort was made to improve the plugin in a variety of ways: WalletConnect support, single receiver mode (accept payments using just one wallet), more networks, automatic ETH rate fetching, improved UI and messaging, and smart contract wallet support. All of these features made it into this version of the plugin, except for smart contract wallet support - issues processing transactions stemming from sc wallets meant that we ultimately had to turn away sc wallet payments altogether.

Released under the terms of the Apache License 2.0
For Devcon 7, 3cities was [adopted](https://github.com/efdevcon/DIPs/blob/master/DIPs/DIP-37.md) for ticket payments. 3cities is a decentralized, open-source offchain payment processor to help abstract over wallets, chains, tokens, currencies, and payment methods.
2 changes: 1 addition & 1 deletion pretix_eth/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "3.0.0-dev"
__version__ = "4.0.0"
1 change: 0 additions & 1 deletion pretix_eth/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from . import __version__


class EthApp(AppConfig):
name = 'pretix_eth'
verbose_name = 'Pretix Ethereum Payment Provider'
Expand Down
67 changes: 43 additions & 24 deletions pretix_eth/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
OrderRefund,
)

from web3 import Web3

from pretix_eth.models import SignedMessage
from pretix_eth.network.tokens import IToken, \
all_token_and_network_ids_to_tokens

import pytz

Expand All @@ -28,33 +24,47 @@ def payment_to_row(payment):
else:
completion_date = ''

currency_type = payment.info_data.get("currency_type", "")
token: IToken = all_token_and_network_ids_to_tokens.get(currency_type, None)

if token is None:
chain_id = currency_type
token_address = f"Missing ERC20 contract data for {currency_type}"
else:
chain_id = token.CHAIN_ID
token_address = token.ADDRESS

primary_currency = payment.info_data.get("primary_currency", "")
fiat_amount = payment.amount
token_amount = payment.info_data.get("amount", "")
token_rate = payment.info_data.get("token_rate", "")
usd_per_eth = payment.info_data.get("usd_per_eth", "")

confirmed_transaction: SignedMessage = payment.signed_messages.filter(
is_confirmed=True).first()
if confirmed_transaction is None:
confirmed_transaction: SignedMessage = payment.signed_messages.last()

if confirmed_transaction is not None:
verification_failed_permanently = confirmed_transaction.verification_failed_permanently
verification_explanation = confirmed_transaction.verification_explanation
sender_address = confirmed_transaction.sender_address
recipient_address = confirmed_transaction.recipient_address
transaction_hash = confirmed_transaction.transaction_hash
chain_id = confirmed_transaction.chain_id
chain_name = confirmed_transaction.chain_name
receipt_url = confirmed_transaction.receipt_url
token_currency = confirmed_transaction.token_currency
token_ticker = confirmed_transaction.token_ticker
token_name = confirmed_transaction.token_name
token_amount = confirmed_transaction.token_amount
token_decimals = confirmed_transaction.token_decimals
token_contract_address = confirmed_transaction.token_contract_address
is_testnet = confirmed_transaction.is_testnet
else:
verification_failed_permanently = None
verification_explanation = None
sender_address = None
recipient_address = None
transaction_hash = None
chain_id = None
chain_name = None
receipt_url = None
token_currency = None
token_ticker = None
token_name = None
token_amount = None
token_decimals = None
token_contract_address = None
is_testnet = None

row = [
"Payment",
Expand All @@ -64,15 +74,24 @@ def payment_to_row(payment):
date_to_string(time_zone, payment.created),
completion_date,
payment.state,
verification_failed_permanently,
verification_explanation,
fiat_amount,
Web3.from_wei(int(token_amount), 'ether'),
currency_type,
primary_currency,
sender_address,
recipient_address,
transaction_hash,
chain_id,
token_address,
token_rate,
chain_name,
usd_per_eth,
receipt_url,
token_currency,
token_ticker,
token_name,
token_amount,
token_decimals,
token_contract_address,
is_testnet,
]

return row
Expand All @@ -84,10 +103,10 @@ class EthereumOrdersExporter(ListExporter):

headers = (
'Type', 'Event slug', 'Order', 'Payment ID', 'Creation date',
'Completion date', 'Status', 'Fiat Amount', 'Token Amount', 'Token',
'ETH or DAI sender address', 'ETH or DAI receiver address',
'Transaction Hash', 'Chain ID', 'DAI contract address',
'Token Rate at time of order',
'Completion date', 'Status', 'Verification Failed Permanently', 'Verification Explanation', 'Fiat Amount', 'Currency Type',
'Sender address', 'Receiver address',
'Transaction Hash', 'Chain ID', 'Chain Name', 'Order USD/ETH Rate',
'Receipt URL', 'Token Currency', 'Token Ticker', 'Token Name', 'Token Amount', 'Token Decimals', 'Token Contract Address', 'Is Testnet'
)

@property
Expand Down
53 changes: 0 additions & 53 deletions pretix_eth/forms.py

This file was deleted.

Loading