Skip to content

Commit 997a15d

Browse files
committed
fix(tokens): only persist/hydrate upon fetching metadata if we have an account
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 8ff9cfd commit 997a15d

3 files changed

Lines changed: 345 additions & 6 deletions

File tree

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
{
2+
"formatVersion": 1,
3+
"database": {
4+
"version": 13,
5+
"identityHash": "04a962ce0415479decb938be6f7ef584",
6+
"entities": [
7+
{
8+
"tableName": "messages",
9+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`idBase58` TEXT NOT NULL, `text` TEXT NOT NULL, `amountUsdc` INTEGER, `amountNative` INTEGER, `nativeCurrency` TEXT, `rate` REAL, `state` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, `metadata` TEXT, `mintBase58` TEXT DEFAULT 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', PRIMARY KEY(`idBase58`))",
10+
"fields": [
11+
{
12+
"fieldPath": "idBase58",
13+
"columnName": "idBase58",
14+
"affinity": "TEXT",
15+
"notNull": true
16+
},
17+
{
18+
"fieldPath": "text",
19+
"columnName": "text",
20+
"affinity": "TEXT",
21+
"notNull": true
22+
},
23+
{
24+
"fieldPath": "amountUsdc",
25+
"columnName": "amountUsdc",
26+
"affinity": "INTEGER"
27+
},
28+
{
29+
"fieldPath": "amountNative",
30+
"columnName": "amountNative",
31+
"affinity": "INTEGER"
32+
},
33+
{
34+
"fieldPath": "nativeCurrency",
35+
"columnName": "nativeCurrency",
36+
"affinity": "TEXT"
37+
},
38+
{
39+
"fieldPath": "rate",
40+
"columnName": "rate",
41+
"affinity": "REAL"
42+
},
43+
{
44+
"fieldPath": "state",
45+
"columnName": "state",
46+
"affinity": "TEXT",
47+
"notNull": true
48+
},
49+
{
50+
"fieldPath": "timestamp",
51+
"columnName": "timestamp",
52+
"affinity": "INTEGER",
53+
"notNull": true
54+
},
55+
{
56+
"fieldPath": "metadata",
57+
"columnName": "metadata",
58+
"affinity": "TEXT"
59+
},
60+
{
61+
"fieldPath": "mintBase58",
62+
"columnName": "mintBase58",
63+
"affinity": "TEXT",
64+
"defaultValue": "'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'"
65+
}
66+
],
67+
"primaryKey": {
68+
"autoGenerate": false,
69+
"columnNames": [
70+
"idBase58"
71+
]
72+
}
73+
},
74+
{
75+
"tableName": "tokens",
76+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `decimals` INTEGER NOT NULL, `name` TEXT NOT NULL, `symbol` TEXT NOT NULL, `created_at` INTEGER, `description` TEXT NOT NULL, `image_url` TEXT NOT NULL, `social_links` TEXT, `bill_customizations` TEXT, `vm_vm` TEXT NOT NULL, `vm_authority` TEXT NOT NULL, `vm_lock_duration_days` INTEGER NOT NULL, `lp_currency_config` TEXT, `lp_liquidity_pool` TEXT, `lp_seed` TEXT, `lp_authority` TEXT, `lp_mint_vault` TEXT, `lp_core_mint_vault` TEXT, `lp_circulating_supply_quarks` INTEGER, `lp_sell_fee_bps` INTEGER, `lp_price_amount_usd` REAL, `lp_market_cap_amount_usd` REAL, PRIMARY KEY(`address`))",
77+
"fields": [
78+
{
79+
"fieldPath": "address",
80+
"columnName": "address",
81+
"affinity": "TEXT",
82+
"notNull": true
83+
},
84+
{
85+
"fieldPath": "decimals",
86+
"columnName": "decimals",
87+
"affinity": "INTEGER",
88+
"notNull": true
89+
},
90+
{
91+
"fieldPath": "name",
92+
"columnName": "name",
93+
"affinity": "TEXT",
94+
"notNull": true
95+
},
96+
{
97+
"fieldPath": "symbol",
98+
"columnName": "symbol",
99+
"affinity": "TEXT",
100+
"notNull": true
101+
},
102+
{
103+
"fieldPath": "createdAt",
104+
"columnName": "created_at",
105+
"affinity": "INTEGER"
106+
},
107+
{
108+
"fieldPath": "description",
109+
"columnName": "description",
110+
"affinity": "TEXT",
111+
"notNull": true
112+
},
113+
{
114+
"fieldPath": "imageUrl",
115+
"columnName": "image_url",
116+
"affinity": "TEXT",
117+
"notNull": true
118+
},
119+
{
120+
"fieldPath": "socialLinks",
121+
"columnName": "social_links",
122+
"affinity": "TEXT"
123+
},
124+
{
125+
"fieldPath": "billCustomizationsJson",
126+
"columnName": "bill_customizations",
127+
"affinity": "TEXT"
128+
},
129+
{
130+
"fieldPath": "vmMetadata.vm",
131+
"columnName": "vm_vm",
132+
"affinity": "TEXT",
133+
"notNull": true
134+
},
135+
{
136+
"fieldPath": "vmMetadata.authority",
137+
"columnName": "vm_authority",
138+
"affinity": "TEXT",
139+
"notNull": true
140+
},
141+
{
142+
"fieldPath": "vmMetadata.lockDurationInDays",
143+
"columnName": "vm_lock_duration_days",
144+
"affinity": "INTEGER",
145+
"notNull": true
146+
},
147+
{
148+
"fieldPath": "launchpadMetadata.currencyConfig",
149+
"columnName": "lp_currency_config",
150+
"affinity": "TEXT"
151+
},
152+
{
153+
"fieldPath": "launchpadMetadata.liquidityPool",
154+
"columnName": "lp_liquidity_pool",
155+
"affinity": "TEXT"
156+
},
157+
{
158+
"fieldPath": "launchpadMetadata.seed",
159+
"columnName": "lp_seed",
160+
"affinity": "TEXT"
161+
},
162+
{
163+
"fieldPath": "launchpadMetadata.authority",
164+
"columnName": "lp_authority",
165+
"affinity": "TEXT"
166+
},
167+
{
168+
"fieldPath": "launchpadMetadata.mintVault",
169+
"columnName": "lp_mint_vault",
170+
"affinity": "TEXT"
171+
},
172+
{
173+
"fieldPath": "launchpadMetadata.coreMintVault",
174+
"columnName": "lp_core_mint_vault",
175+
"affinity": "TEXT"
176+
},
177+
{
178+
"fieldPath": "launchpadMetadata.currentCirculatingSupplyQuarks",
179+
"columnName": "lp_circulating_supply_quarks",
180+
"affinity": "INTEGER"
181+
},
182+
{
183+
"fieldPath": "launchpadMetadata.sellFeeBps",
184+
"columnName": "lp_sell_fee_bps",
185+
"affinity": "INTEGER"
186+
},
187+
{
188+
"fieldPath": "launchpadMetadata.priceAmount",
189+
"columnName": "lp_price_amount_usd",
190+
"affinity": "REAL"
191+
},
192+
{
193+
"fieldPath": "launchpadMetadata.marketCapAmount",
194+
"columnName": "lp_market_cap_amount_usd",
195+
"affinity": "REAL"
196+
}
197+
],
198+
"primaryKey": {
199+
"autoGenerate": false,
200+
"columnNames": [
201+
"address"
202+
]
203+
}
204+
},
205+
{
206+
"tableName": "token_social_links",
207+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `token_address` TEXT NOT NULL, `type` TEXT NOT NULL, `value` TEXT NOT NULL, FOREIGN KEY(`token_address`) REFERENCES `tokens`(`address`) ON UPDATE NO ACTION ON DELETE CASCADE )",
208+
"fields": [
209+
{
210+
"fieldPath": "id",
211+
"columnName": "id",
212+
"affinity": "INTEGER",
213+
"notNull": true
214+
},
215+
{
216+
"fieldPath": "tokenAddress",
217+
"columnName": "token_address",
218+
"affinity": "TEXT",
219+
"notNull": true
220+
},
221+
{
222+
"fieldPath": "type",
223+
"columnName": "type",
224+
"affinity": "TEXT",
225+
"notNull": true
226+
},
227+
{
228+
"fieldPath": "value",
229+
"columnName": "value",
230+
"affinity": "TEXT",
231+
"notNull": true
232+
}
233+
],
234+
"primaryKey": {
235+
"autoGenerate": true,
236+
"columnNames": [
237+
"id"
238+
]
239+
},
240+
"indices": [
241+
{
242+
"name": "index_token_social_links_token_address",
243+
"unique": false,
244+
"columnNames": [
245+
"token_address"
246+
],
247+
"orders": [],
248+
"createSql": "CREATE INDEX IF NOT EXISTS `index_token_social_links_token_address` ON `${TABLE_NAME}` (`token_address`)"
249+
}
250+
],
251+
"foreignKeys": [
252+
{
253+
"table": "tokens",
254+
"onDelete": "CASCADE",
255+
"onUpdate": "NO ACTION",
256+
"columns": [
257+
"token_address"
258+
],
259+
"referencedColumns": [
260+
"address"
261+
]
262+
}
263+
]
264+
},
265+
{
266+
"tableName": "token_valuation",
267+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`token_address` TEXT NOT NULL, `balance_quarks` INTEGER NOT NULL, `cost_basis` REAL NOT NULL, PRIMARY KEY(`token_address`), FOREIGN KEY(`token_address`) REFERENCES `tokens`(`address`) ON UPDATE NO ACTION ON DELETE CASCADE )",
268+
"fields": [
269+
{
270+
"fieldPath": "tokenAddress",
271+
"columnName": "token_address",
272+
"affinity": "TEXT",
273+
"notNull": true
274+
},
275+
{
276+
"fieldPath": "balanceQuarks",
277+
"columnName": "balance_quarks",
278+
"affinity": "INTEGER",
279+
"notNull": true
280+
},
281+
{
282+
"fieldPath": "costBasis",
283+
"columnName": "cost_basis",
284+
"affinity": "REAL",
285+
"notNull": true
286+
}
287+
],
288+
"primaryKey": {
289+
"autoGenerate": false,
290+
"columnNames": [
291+
"token_address"
292+
]
293+
},
294+
"indices": [
295+
{
296+
"name": "index_token_valuation_token_address",
297+
"unique": false,
298+
"columnNames": [
299+
"token_address"
300+
],
301+
"orders": [],
302+
"createSql": "CREATE INDEX IF NOT EXISTS `index_token_valuation_token_address` ON `${TABLE_NAME}` (`token_address`)"
303+
}
304+
],
305+
"foreignKeys": [
306+
{
307+
"table": "tokens",
308+
"onDelete": "CASCADE",
309+
"onUpdate": "NO ACTION",
310+
"columns": [
311+
"token_address"
312+
],
313+
"referencedColumns": [
314+
"address"
315+
]
316+
}
317+
]
318+
}
319+
],
320+
"setupQueries": [
321+
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
322+
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '04a962ce0415479decb938be6f7ef584')"
323+
]
324+
}
325+
}

apps/flipcash/shared/persistence/db/src/main/kotlin/com/flipcash/app/persistence/FlipcashDatabase.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ import org.kin.sdk.base.tools.subByteArray
4242
AutoMigration(from = 9, to = 10, spec = FlipcashDatabase.Migration9To10::class),
4343
AutoMigration(from = 10, to = 11, spec = FlipcashDatabase.Migration10To11::class),
4444
AutoMigration(from = 11, to = 12),
45+
AutoMigration(from = 12, to = 13, spec = FlipcashDatabase.Migration12To13::class),
4546
],
46-
version = 12,
47+
version = 13,
4748
)
4849
@TypeConverters(TokenTypeConverters::class)
4950
abstract class FlipcashDatabase : RoomDatabase() {
@@ -117,6 +118,13 @@ abstract class FlipcashDatabase : RoomDatabase() {
117118
)
118119
class Migration10To11 : Migration(10, 11), AutoMigrationSpec
119120

121+
class Migration12To13 : Migration(12, 13), AutoMigrationSpec {
122+
override fun migrate(db: SupportSQLiteDatabase) {
123+
db.execSQL("DELETE FROM tokens")
124+
db.execSQL("DELETE FROM token_valuation")
125+
}
126+
}
127+
120128
companion object {
121129
private var instance: FlipcashDatabase? = null
122130
fun requireInstance() = requireNotNull(instance)

apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenCoordinator.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.lifecycle.DefaultLifecycleObserver
1111
import androidx.lifecycle.LifecycleOwner
1212
import androidx.lifecycle.ProcessLifecycleOwner
1313
import com.flipcash.app.persistence.sources.TokenDataSource
14+
import com.getcode.opencode.controllers.AccountController
1415
import com.getcode.opencode.controllers.TokenController
1516
import com.getcode.opencode.exchange.Exchange
1617
import com.getcode.opencode.internal.model.WindowedRange
@@ -77,6 +78,7 @@ import javax.inject.Singleton
7778
class TokenCoordinator @Inject constructor(
7879
@param:ApplicationContext private val context: Context,
7980
private val tokenController: TokenController,
81+
private val accountController: AccountController,
8082
private val networkObserver: NetworkConnectivityListener,
8183
private val exchange: Exchange,
8284
private val dataSource: TokenDataSource,
@@ -229,11 +231,15 @@ class TokenCoordinator @Inject constructor(
229231

230232
return tokenController.getTokenMetadata(mint)
231233
.onSuccess { result ->
232-
// Persist to Room
233-
dataSource.upsert(listOf(result.token))
234-
// Hydrate in-memory
235-
_state.update { state ->
236-
state.copy(tokens = state.tokens + (result.token.address to result.token))
234+
val hasAccount = accountController.hasAccountFor(result.token.address)
235+
// if we have an account for this mint, persist and hydrate
236+
if (hasAccount) {
237+
// Persist to Room
238+
dataSource.upsert(listOf(result.token))
239+
// Hydrate in-memory
240+
_state.update { state ->
241+
state.copy(tokens = state.tokens + (result.token.address to result.token))
242+
}
237243
}
238244
}
239245
}

0 commit comments

Comments
 (0)