@@ -185,46 +185,44 @@ settingsRoutes.put('/primary', async (c) => {
185185 return c . json ( { error : 'Handle already taken by another wallet' } , 409 ) ;
186186 }
187187
188- // Batch update: switch primary(更新所有 FK 子表)
189- // SQLite: PRAGMA defer_foreign_keys must be set BEFORE the transaction starts.
190- await c . env . DB . prepare ( "PRAGMA defer_foreign_keys = ON" ) . run ( ) ;
188+ // Switch primary: Insert new handle → migrate children → delete old handle.
189+ // No PRAGMA needed — avoids D1's unreliable FK deferral.
190+ const oldAccount = await c . env . DB . prepare (
191+ 'SELECT handle, wallet, basename, webhook_url, created_at, tx_hash FROM accounts WHERE wallet = ?'
192+ ) . bind ( auth . wallet ) . first < { handle : string ; wallet : string ; basename : string | null ; webhook_url : string | null ; created_at : number ; tx_hash : string | null } > ( ) ;
193+
194+ if ( ! oldAccount ) {
195+ return c . json ( { error : 'Account not found' } , 500 ) ;
196+ }
197+
198+ // Insert new handle with temp wallet to avoid UNIQUE conflict
199+ const tempWallet = `SWITCH_${ Date . now ( ) } ` ;
200+ await c . env . DB . prepare (
201+ 'INSERT INTO accounts (handle, wallet, basename, webhook_url, created_at, tx_hash) VALUES (?, ?, ?, ?, ?, ?)'
202+ ) . bind ( newHandle , tempWallet , alias . basename , oldAccount . webhook_url , oldAccount . created_at , oldAccount . tx_hash ) . run ( ) ;
203+
204+ // Migrate children, delete old, fix wallet — all in one atomic batch
191205 await c . env . DB . batch ( [
192- // Update account handle
193- c . env . DB . prepare ( 'UPDATE accounts SET handle = ?, basename = ? WHERE wallet = ?' )
194- . bind ( newHandle , alias . basename , auth . wallet ) ,
195- // Migrate all child tables with FK on accounts(handle)
196- c . env . DB . prepare ( 'UPDATE emails SET handle = ? WHERE handle = ?' )
197- . bind ( newHandle , oldHandle ) ,
198- c . env . DB . prepare ( 'UPDATE refresh_tokens SET handle = ? WHERE handle = ?' )
199- . bind ( newHandle , oldHandle ) ,
200- c . env . DB . prepare ( 'UPDATE api_keys SET handle = ? WHERE handle = ?' )
201- . bind ( newHandle , oldHandle ) ,
202- c . env . DB . prepare ( 'UPDATE attention_config SET handle = ? WHERE handle = ?' )
203- . bind ( newHandle , oldHandle ) ,
204- c . env . DB . prepare ( 'UPDATE attention_bonds SET sender_handle = ? WHERE sender_handle = ?' )
205- . bind ( newHandle , oldHandle ) ,
206- c . env . DB . prepare ( 'UPDATE attention_bonds SET recipient_handle = ? WHERE recipient_handle = ?' )
207- . bind ( newHandle , oldHandle ) ,
208- c . env . DB . prepare ( 'UPDATE attention_whitelist SET recipient_handle = ? WHERE recipient_handle = ?' )
209- . bind ( newHandle , oldHandle ) ,
210- c . env . DB . prepare ( 'UPDATE sender_reputation SET sender_handle = ? WHERE sender_handle = ?' )
211- . bind ( newHandle , oldHandle ) ,
212- c . env . DB . prepare ( 'UPDATE sender_reputation SET recipient_handle = ? WHERE recipient_handle = ?' )
213- . bind ( newHandle , oldHandle ) ,
214- c . env . DB . prepare ( 'UPDATE qaf_scores SET handle = ? WHERE handle = ?' )
215- . bind ( newHandle , oldHandle ) ,
216- c . env . DB . prepare ( 'UPDATE world_id_verifications SET handle = ? WHERE handle = ?' )
217- . bind ( newHandle , oldHandle ) ,
218- c . env . DB . prepare ( 'UPDATE escrow_claims SET sender_handle = ? WHERE sender_handle = ?' )
219- . bind ( newHandle , oldHandle ) ,
220- c . env . DB . prepare ( 'UPDATE escrow_claims SET claimer_handle = ? WHERE claimer_handle = ?' )
221- . bind ( newHandle , oldHandle ) ,
222- // Reset all is_primary flags for this wallet
223- c . env . DB . prepare ( 'UPDATE basename_aliases SET is_primary = 0 WHERE wallet = ?' )
224- . bind ( auth . wallet ) ,
225- // Set new primary
226- c . env . DB . prepare ( 'UPDATE basename_aliases SET is_primary = 1 WHERE handle = ? AND wallet = ?' )
227- . bind ( newHandle , auth . wallet ) ,
206+ c . env . DB . prepare ( 'UPDATE emails SET handle = ? WHERE handle = ?' ) . bind ( newHandle , oldHandle ) ,
207+ c . env . DB . prepare ( 'UPDATE refresh_tokens SET handle = ? WHERE handle = ?' ) . bind ( newHandle , oldHandle ) ,
208+ c . env . DB . prepare ( 'UPDATE api_keys SET handle = ? WHERE handle = ?' ) . bind ( newHandle , oldHandle ) ,
209+ c . env . DB . prepare ( 'UPDATE attention_config SET handle = ? WHERE handle = ?' ) . bind ( newHandle , oldHandle ) ,
210+ c . env . DB . prepare ( 'UPDATE attention_bonds SET sender_handle = ? WHERE sender_handle = ?' ) . bind ( newHandle , oldHandle ) ,
211+ c . env . DB . prepare ( 'UPDATE attention_bonds SET recipient_handle = ? WHERE recipient_handle = ?' ) . bind ( newHandle , oldHandle ) ,
212+ c . env . DB . prepare ( 'UPDATE attention_whitelist SET recipient_handle = ? WHERE recipient_handle = ?' ) . bind ( newHandle , oldHandle ) ,
213+ c . env . DB . prepare ( 'UPDATE sender_reputation SET sender_handle = ? WHERE sender_handle = ?' ) . bind ( newHandle , oldHandle ) ,
214+ c . env . DB . prepare ( 'UPDATE sender_reputation SET recipient_handle = ? WHERE recipient_handle = ?' ) . bind ( newHandle , oldHandle ) ,
215+ c . env . DB . prepare ( 'UPDATE qaf_scores SET handle = ? WHERE handle = ?' ) . bind ( newHandle , oldHandle ) ,
216+ c . env . DB . prepare ( 'UPDATE world_id_verifications SET handle = ? WHERE handle = ?' ) . bind ( newHandle , oldHandle ) ,
217+ c . env . DB . prepare ( 'UPDATE escrow_claims SET sender_handle = ? WHERE sender_handle = ?' ) . bind ( newHandle , oldHandle ) ,
218+ c . env . DB . prepare ( 'UPDATE escrow_claims SET claimer_handle = ? WHERE claimer_handle = ?' ) . bind ( newHandle , oldHandle ) ,
219+ // Delete old account (children already migrated)
220+ c . env . DB . prepare ( 'DELETE FROM accounts WHERE handle = ?' ) . bind ( oldHandle ) ,
221+ // Fix wallet on new account
222+ c . env . DB . prepare ( 'UPDATE accounts SET wallet = ? WHERE handle = ?' ) . bind ( auth . wallet , newHandle ) ,
223+ // Update basename_aliases
224+ c . env . DB . prepare ( 'UPDATE basename_aliases SET is_primary = 0 WHERE wallet = ?' ) . bind ( auth . wallet ) ,
225+ c . env . DB . prepare ( 'UPDATE basename_aliases SET is_primary = 1 WHERE handle = ? AND wallet = ?' ) . bind ( newHandle , auth . wallet ) ,
228226 ] ) ;
229227
230228 // Issue new token
0 commit comments