Blog - How does ValStore work?
What is Valstore?
ValStore is an open source Valorant Shop viewer containing VALORANTs daily, accessory and Night Market shop.This project is not affiliated with Riot Games. You can find the entire source code on GitHub.
For building the app I used an inoffical api provided by Not0fficer for Skin data
and the Documentations of the official Riot Games API created by techchrism.
Make sure to check them out, they did amazing work! The project wouldn't be possible without them.
View ValStore on GitHub
Authentication
ValStore uses the official Riot Games API to authenticate users and fetch their shop data.How do you authenticate?
Via the webview_flutter package youre redirected to the official Riot Games login page. To be exact towards this url:static String newLoginUrl = "https://auth.riotgames.com/authorize?redirect_uri=https%3A%2F%2Fplayvalorant.com%2Fopt_in&client_id=play-valorant-web-prod&response_type=token%20id_token&nonce=1&scope=account%20openid";
After successful login you're redirected back to the app, the webview returns the access token to the app. This token is used to fetch the shop data.
Reauthentication
The cookies of the webview can be used to directly reauthenticate you on the restart of the app. This happens only if you've already logged in once and checked the "Keep signed in" box.Data Fetching
The app fetches the shop data from the official Riot Games API. Those are the same endpoints the game uses. The data is fetched every time you open the app. The data is not saved locally. To be exact the "GetStorefront" endpoint is used to fetch the daily shop and night market data.Endpoint Documentation
Database
Over the time I built a database containing all the skins and their rarities and levels. This is stored in a firestore database. The database is used to display the skins in the app. Additionally the database is used to store the users wishlist.Data structure
Skins:
{
"skins": [
{
"name": "SkinName",
"offerId": "OfferId - most of the times first level",
"skinId": "SkinId",
"levels": [],
"chromas: [],
"content_tier": {
"color": "Color in Hex",
"icon": "URL",
"name": "TierName aka Deluxe, Premium, ..."
},
"image": "URL",
"cost": 1275
}
]
}
Wishlist:
{
"users": [
{
"userId": "uniqueUserId - this is publicly visible",
"wishlist": ["skinId1", "skinId2"]
}
]
}