Przejdź do treści
ArchXS

Realizacje · Produkty własne, Web3 konsumencki

Album kolekcjonerski na NFT z analityką trzymaną u siebie

Jak zbudować produkt konsumencki na danych z blockchaina, w którym ciekawą pracą nie jest łańcuch, tylko indeksacja, tożsamość i silnik analityczny, który nie wysyła kolekcji użytkownika do cudzego API.

1 100+ źródeł Javy, 239 migracji schematu
Backend
8 funkcji, inferencja na własnej infrastrukturze
Analityka
Web, Android i iOS z jednego monorepo
Wydania
Album kolekcjonerski na NFT z analityką trzymaną u siebie
Rys. 01Produkty własne, Web3 konsumencki

Kontekst

Bindaro to nasz własny produkt: miejsce, w którym posiadacz NFT układa je w album, opisuje, publikuje wynik i daje się znaleźć innym kolekcjonerom. Pod spodem siedzi marketplace, model rzadkości i punktacji, silnik analityczny oraz bot na Discordzie, dostarczone jako aplikacja webowa i aplikacje mobilne na Androida i iOS.

Problem

Kolekcjoner ma już portfel i marketplace. Nie ma miejsca, w którym kolekcja jest obiektem kuratorowanym, a nie listą posiadanych tokenów posortowaną po adresie kontraktu. To problem produktowy, który niemal natychmiast rozpada się na trzy inżynierskie.

Pierwszy: blockchain jest fatalnym modelem odczytowym. Własność, metadane, ceny podłogi i historia aktywności mieszkają w różnych miejscach, docierają w różnym tempie i bywają ze sobą niezgodne; pytanie łańcucha w momencie renderowania strony daje produkt, który jest wolny, kiedy działa, i pusty, kiedy węzeł ma zły dzień.

Drugi: tożsamość. Odbiorcy dzielą się na tych, którzy przychodzą z portfelem, i tych, którzy przychodzą z adresem e-mail i bez zamiaru uczenia się, czym jest seed phrase. Obsługa wyłącznie pierwszych to produkt dla ludzi, którzy mają już trzy takie. Obsługa wyłącznie drugich oznacza, że platforma nie potrafi udowodnić, że ktokolwiek cokolwiek posiada.

Trzeci: analityka. Rzadkość, wycena i sygnały zakupowe są powodem, dla którego produkt otwiera się drugi raz. Robienie tego przez hostowane API modelu oznacza, że przy każdym zapytaniu portfel użytkownika i wyprowadzona z niego sytuacja finansowa opuszczają naszą infrastrukturę, a koszt rośnie wraz z ciekawością, nie z przychodem.

Podejście

Odczyt łańcucha schowaliśmy za własnym stanem. Backend na Quarkusie, PostgreSQL jako model odczytowy z migracjami trzymanymi w repozytorium, Redis na to, czego nie warto liczyć ponownie, S3 na media. Aplikacje rozmawiają z GraphQL i REST, nigdy z węzłem. To sprawia, że strona albumu otwiera się w tempie strony, a nie w tempie łańcucha, i to samo powoduje, że produkt degraduje się łagodnie, zamiast padać, kiedy źródło zwalnia.

Tożsamość rozwiązaliśmy przez niewybieranie. Z przodu stoi Keycloak, przyjmując podpis portfela, kod OTP na e-mail i logowanie społecznościowe jako metody uwierzytelnienia jednego konta, z portfelem osadzonym, tworzonym dla tych, którzy przychodzą bez własnego. Strona podpisowa to osobna praca z własnym opisem; z perspektywy Bindaro istotne jest, że platforma ma jeden rejestr użytkowników, jeden ślad audytowy i jedno miejsce odbierania dostępu.

Silnik analityczny, BindaroAI, działa na naszej infrastrukturze na modelach self-hosted i była to decyzja architektoniczna, nie optymalizacja kosztu. Osiem funkcji: rekomendacje, wgląd w rzadkość, sygnały cenowe, klasyfikacja, wycena, porównanie kolekcji, wykrywanie wzorców i kuratorskie ekspozycje, z których każda jest promptem po danych, które już mamy, przy niskiej temperaturze, bo wynik ma być na tyle powtarzalny, żeby dało się z nim polemizować. Kolekcja użytkownika nie jest wsadem do cudzego serwisu.

Mechaniki rynkowej nie wymyślaliśmy od nowa: oferty i wystawienia działają na Seaporcie, obejmując ERC-721 i ERC-1155, więc powiernictwo i rozliczenie idą protokołem, który audytowali ludzie robiący to zawodowo.

Strona kliencka to jedno monorepo, aplikacja webowa w Next.js i aplikacja Expo wydawana do Play Store i TestFlight, dzielące klienta API, auth, system projektowy i tłumaczenia jako pakiety. Aplikacja mobilna nie jest opakowaniem strony i nie jest drugą bazą kodu udającą zgodność z pierwszą.

Rezultat

Produkt działa produkcyjnie w wersji webowej, w otwartych testach na Androidzie i w zamkniętych na iOS, na backendzie liczącym ponad tysiąc sto źródeł Javy i dwieście trzydzieści dziewięć migracji schematu, co jest uczciwszą miarą rzeczywistej powierzchni platformy niż lista funkcji.

Koszty tych decyzji są widoczne. Własny model odczytowy to własny problem uzgadniania: każde odświeżenie metadanych, każda cena podłogi, każda zmiana własności są czymś, co musimy utrzymywać w zgodzie z łańcuchem, i nie ma wersji tego zadania, która jest darmowa. Inferencja u siebie oznacza, że sprzęt, aktualizacje modeli i budżet opóźnień są nasze, zamiast płacić komuś, żeby były jego.

Wnioski

W produkcie stojącym na danych publicznych pytaniem architektonicznym jest, gdzie mieszka autorytatywny model odczytowy. Odpowiedź wczesna sprawia, że wszystko dalej jest cachem ze znaną historią odświeżania. Odpowiedź późna, przez dokładanie cache'ów tam, gdzie strona wydawała się wolna, daje system, w którym nikt nie potrafi powiedzieć, co jest prawdą.

Drugi wniosek dotyczy funkcji AI w produkcie konsumenckim. Ciekawą decyzją prawie nigdy nie jest, który model, tylko co wychodzi poza budynek. Kiedy w żądaniu są posiadane aktywa i wyprowadzona z nich zamożność, wybór dostawcy przestaje być pytaniem zakupowym, a staje się architektonicznym.

Wróć do realizacje