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

⚠️ Third Party Wallet Support [PAY-2949][PAY-2948][PAY-2950] #8611

Merged
merged 29 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
17030db
Add user_payout_wallet_history_table
rickyrombo May 24, 2024
acb8940
Fix mypy and flake8 config
rickyrombo May 24, 2024
4573ceb
support indexing new purchase gate, keep backwards compatibility
rickyrombo May 24, 2024
0bd1bfd
fix mypy problem
rickyrombo May 24, 2024
f4bd876
update user payout wallet history in indexing
rickyrombo May 24, 2024
547db11
Add endpoints to get access info
rickyrombo May 24, 2024
fc801d0
migrate legacy purchase gates to new purchase gates
rickyrombo May 24, 2024
679828d
Change names
rickyrombo May 24, 2024
cb33ca6
Fix track endpoint
rickyrombo May 24, 2024
d5ad9f8
generate sdk
rickyrombo May 24, 2024
7023105
update sdk to use new types
rickyrombo May 24, 2024
f257d77
fix logger in entity manager
rickyrombo May 24, 2024
655c97b
fix genre in upload-track to not be "All Genres"
rickyrombo May 24, 2024
b7a656d
Make payout wallet history allow nullable payout wallets
rickyrombo May 25, 2024
fd7dab1
Add transaction helper method to APIs
rickyrombo May 25, 2024
4c0e872
fix playlist access-info
rickyrombo May 28, 2024
f3fc6e4
move access info back to full tracks only
rickyrombo May 28, 2024
2a2cae0
return playlist access info to full endpoint only
rickyrombo May 28, 2024
05724d9
add conversion to user bank indexer
rickyrombo May 29, 2024
42a0644
Fix purchase splits, add test
rickyrombo May 29, 2024
d0c93fd
safer iteration
rickyrombo May 29, 2024
b1a3a3c
allow 6 decimal places for percentages
rickyrombo May 29, 2024
3fb8027
remove "legacy" flag and make separate method instead
rickyrombo May 29, 2024
7194819
change how legacy works for typing reasons, add test
rickyrombo May 29, 2024
1b99430
Fix tests, move logic out of "validation"
rickyrombo May 30, 2024
0356fd7
add description
rickyrombo May 30, 2024
88eef78
remove unnecessary int()
rickyrombo May 30, 2024
364df48
move commit
rickyrombo May 30, 2024
c4d9cda
change comments
rickyrombo May 31, 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
10 changes: 3 additions & 7 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@
"reportMissingModuleSource": "none"
},
"python.languageServer": "Pylance",
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
"python.linting.flake8Args": [
"mypy-type-checker.args": [
"--config",
"packages/discovery-provider/setup.cfg"
],
"python.linting.lintOnSave": true,
"python.linting.mypyEnabled": true,
"flake8.args": ["--config", "packages/discovery-provider/setup.cfg"],

"isort.args": ["--settings-path", "packages/discovery-provider/setup.cfg"],
"mypy.configFile": "packages/discovery-provider/setup.cfg",
"mypy.runUsingActiveInterpreter": true,
"python.analysis.indexing": true,
"python.testing.pytestEnabled": true,
"python.testing.unittestEnabled": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/commands/src/upload-track.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ program
genre:
genre ||
Genre[
Object.keys(Genre)[randomInt(Object.keys(Genre).length - 1)]
Object.keys(Genre)[randomInt(Object.keys(Genre).length - 2) + 1]
],
mood: mood || `mood ${rand}`,
credits_splits: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS user_payout_wallet_history (
user_id INTEGER NOT NULL,
spl_usdc_payout_wallet VARCHAR NOT NULL,
blocknumber INTEGER NOT NULL,
block_timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL,
rickyrombo marked this conversation as resolved.
Show resolved Hide resolved
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (user_id, block_timestamp),
CONSTRAINT user_payout_wallet_history_blocknumber_fkey FOREIGN KEY (blocknumber) REFERENCES blocks("number") ON DELETE CASCADE
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
BEGIN TRANSACTION;
rickyrombo marked this conversation as resolved.
Show resolved Hide resolved

-- Update track stream price history
WITH updated_track_stream_splits AS (
SELECT
track_id,
stream_conditions -> 'usdc_purchase' -> 'price' AS price,
jsonb_build_array(
jsonb_build_object('user_id', owner_id, 'percentage', 100.0000)
) as splits
FROM
tracks
WHERE
jsonb_typeof(stream_conditions -> 'usdc_purchase' -> 'splits') = 'object'
)
UPDATE
track_price_history
SET
splits = updated_track_stream_splits.splits
FROM
updated_track_stream_splits
WHERE
updated_track_stream_splits.track_id = track_price_history.track_id
AND track_price_history.access = 'stream';

-- Update track stream conditions
WITH updated_track_stream_splits AS (
SELECT
track_id,
stream_conditions -> 'usdc_purchase' -> 'price' AS price,
jsonb_build_array(
jsonb_build_object('user_id', owner_id, 'percentage', 100.0000)
) as splits
FROM
tracks
WHERE
jsonb_typeof(stream_conditions -> 'usdc_purchase' -> 'splits') = 'object'
Copy link
Member

Choose a reason for hiding this comment

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

do we have non object things still?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is really just IS NOT NULL i guess, but with a tighter safeguard for after this conversion happens to not do it again

)
UPDATE
tracks
SET
stream_conditions = jsonb_build_object(
'usdc_purchase',
jsonb_build_object(
'price',
updated_track_stream_splits.price,
'splits',
updated_track_stream_splits.splits
)
)
FROM
updated_track_stream_splits
WHERE
updated_track_stream_splits.track_id = tracks.track_id;

-- Update track download price history
WITH updated_track_download_splits AS (
SELECT
track_id,
download_conditions -> 'usdc_purchase' -> 'price' AS price,
jsonb_build_array(
jsonb_build_object('user_id', owner_id, 'percentage', 100.0000)
) as splits
FROM
tracks
WHERE
jsonb_typeof(
download_conditions -> 'usdc_purchase' -> 'splits'
) = 'object'
)
UPDATE
track_price_history
SET
splits = updated_track_download_splits.splits
FROM
updated_track_download_splits
WHERE
updated_track_download_splits.track_id = track_price_history.track_id
AND track_price_history.access = 'download';

-- Update track download conditions
WITH updated_track_download_splits AS (
SELECT
track_id,
download_conditions -> 'usdc_purchase' -> 'price' AS price,
jsonb_build_array(
jsonb_build_object('user_id', owner_id, 'percentage', 100.0000)
) as splits
FROM
tracks
WHERE
jsonb_typeof(
download_conditions -> 'usdc_purchase' -> 'splits'
) = 'object'
)
UPDATE
tracks
SET
download_conditions = jsonb_build_object(
'usdc_purchase',
jsonb_build_object(
'price',
updated_track_download_splits.price,
'splits',
updated_track_download_splits.splits
)
)
FROM
updated_track_download_splits
WHERE
updated_track_download_splits.track_id = tracks.track_id;

COMMIT;
rickyrombo marked this conversation as resolved.
Show resolved Hide resolved

-- Update album price history
WITH updated_album_stream_splits AS (
SELECT
playlist_id,
stream_conditions -> 'usdc_purchase' -> 'price' AS price,
jsonb_build_array(
jsonb_build_object(
'user_id',
playlist_owner_id,
'percentage',
100.0000
)
) as splits
FROM
playlists
WHERE
jsonb_typeof(stream_conditions -> 'usdc_purchase' -> 'splits') = 'object'
)
UPDATE
album_price_history
SET
splits = updated_album_stream_splits.splits
FROM
updated_album_stream_splits
WHERE
updated_album_stream_splits.playlist_id = album_price_history.playlist_id;

-- Update album stream conditions
WITH updated_album_stream_splits AS (
SELECT
playlist_id,
stream_conditions -> 'usdc_purchase' -> 'price' AS price,
jsonb_build_array(
jsonb_build_object(
'user_id',
playlist_owner_id,
'percentage',
100.0000
)
) as splits
FROM
playlists
WHERE
jsonb_typeof(stream_conditions -> 'usdc_purchase' -> 'splits') = 'object'
)
UPDATE
playlists
SET
stream_conditions = jsonb_build_object(
'usdc_purchase',
jsonb_build_object(
'price',
updated_album_stream_splits.price,
'splits',
updated_album_stream_splits.splits
)
)
FROM
updated_album_stream_splits
WHERE
updated_album_stream_splits.playlist_id = playlists.playlist_id;
13 changes: 12 additions & 1 deletion packages/discovery-provider/src/api/v1/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from src.api.v1.models.common import full_response
from src.models.rewards.challenge import ChallengeType
from src.queries.get_challenges import ChallengeResponse
from src.queries.get_extended_purchase_gate import get_extended_purchase_gate
from src.queries.get_support_for_user import SupportResponse
from src.queries.get_undisbursed_challenges import UndisbursedChallengeResponse
from src.queries.query_helpers import (
Expand Down Expand Up @@ -391,6 +392,16 @@ def extend_track(track):
duration += float(segment["duration"])
track["duration"] = round(duration)

# Transform new format of splits to legacy format for client compatibility
if "stream_conditions" in track:
track["stream_conditions"] = get_extended_purchase_gate(
track["stream_conditions"], legacy=True
)
if "download_conditions" in track:
track["download_conditions"] = get_extended_purchase_gate(
rickyrombo marked this conversation as resolved.
Show resolved Hide resolved
track["download_conditions"], legacy=True
)

return track


Expand Down Expand Up @@ -652,7 +663,7 @@ def __init__(

@property
def __schema__(self):
if self.doc == False:
if self.doc is False:
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, what's this fixing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

a mypy issue iirc

return None
param = super().__schema__
param["description"] = self.description
Expand Down
52 changes: 52 additions & 0 deletions packages/discovery-provider/src/api/v1/models/access_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@
)
ns.add_model("wild_card_split", wild_card_split)

payment_split = ns.model(
"payment_split",
{
"user_id": fields.Integer(required=True),
"percentage": fields.Float(required=True),
},
)

usdc_gate = ns.model(
"usdc_gate",
{
Expand Down Expand Up @@ -77,3 +85,47 @@
],
),
)


extended_payment_split = ns.clone(
"extended_payment_split",
payment_split,
{
"eth_wallet": fields.String(required=True),
"payout_wallet": fields.String(required=True),
"amount": fields.Integer(required=True),
},
)


extended_usdc_gate = ns.model(
"extended_usdc_gate",
{
"price": fields.Integer(required=True),
"splits": fields.List(fields.Nested(extended_payment_split), required=True),
},
)

extended_purchase_gate = ns.model(
"extended_purchase_gate",
{
"usdc_purchase": fields.Nested(
extended_usdc_gate,
required=True,
description="Must pay the total price and split to the given addresses to unlock",
)
},
)

extended_access_gate = ns.add_model(
"extended_access_gate",
OneOfModel(
"extended_access_gate",
[
fields.Nested(tip_gate),
fields.Nested(follow_gate),
fields.Nested(extended_purchase_gate),
fields.Nested(nft_gate),
],
),
)
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,18 @@ def output(self, key, data, **kwargs):
return None
elif self.default is not None:
return self.default
logs = []
for field in self.model.fields:
try:
marshalled = marshal(value, field.nested)
if value == marshalled:
return value
logs.append(f"marshalled={marshalled}")
except fields.MarshallingError as e:
logger.error(
f"fields.py | NestedOneOf | Failed to marshal key={key} value={value} error={e.msg}"
)
logger.error(
f"fields.py | NestedOneOf | Failed to marshal key={key} value={data}: No matching models."
f"fields.py | NestedOneOf | Failed to marshal key={key} value={value}: No matching models. {logs}"
)
return value
25 changes: 24 additions & 1 deletion packages/discovery-provider/src/api/v1/models/playlists.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from flask_restx import fields

from src.api.v1.models.access_gate import access_gate
from src.api.v1.models.extensions.fields import NestedOneOf
from src.api.v1.models.tracks import track_full
from src.api.v1.models.users import user_model, user_model_full

from .access_gate import access_gate, extended_access_gate
from .common import favorite, ns, repost

playlist_artwork = ns.model(
Expand Down Expand Up @@ -91,3 +91,26 @@
"tracks": fields.List(fields.Nested(track_full), required=True),
},
)

album_access_info = ns.model(
"album_access_info",
{
"access": fields.Nested(
access, description="Describes what access the given user has"
),
"user_id": fields.String(
required=True, description="The user ID of the owner of this album"
),
"blocknumber": fields.Integer(
required=True, description="The blocknumber this album was last updated"
),
"is_stream_gated": fields.Boolean(
description="Whether or not the owner has restricted streaming behind an access gate"
),
"stream_conditions": NestedOneOf(
extended_access_gate,
allow_null=True,
description="How to unlock stream access to the track",
),
},
)
Loading