37 lines
1.3 KiB
TypeScript
37 lines
1.3 KiB
TypeScript
import type { Knex } from 'knex';
|
||
import { db } from '../config/database';
|
||
import { generateUlid } from '../utils/ulid';
|
||
|
||
export interface WalletRow {
|
||
id: string;
|
||
user_id: string;
|
||
chain: string;
|
||
address: string;
|
||
derivation_path: string;
|
||
created_at: Date;
|
||
}
|
||
|
||
export const WalletModel = {
|
||
async findByUserId(userId: string): Promise<WalletRow[]> {
|
||
return db('wallets').where({ user_id: userId });
|
||
},
|
||
|
||
async findByUserAndChain(userId: string, chain: string): Promise<WalletRow | undefined> {
|
||
return db('wallets').where({ user_id: userId, chain }).first();
|
||
},
|
||
|
||
/**
|
||
* Insert wallets. UNIQUE(user_id, chain) на уровне DB предотвращает дубликаты —
|
||
* на конфликт kicks transaction rollback.
|
||
* Используется только из createWallet (custodial bootstrap, one-shot per user).
|
||
* НЕ используем upsertMany — нет легитимного пути менять адрес после генерации.
|
||
*/
|
||
async createMany(
|
||
wallets: { user_id: string; chain: string; address: string; derivation_path: string }[],
|
||
trx?: Knex.Transaction,
|
||
): Promise<WalletRow[]> {
|
||
const withIds = wallets.map((w) => ({ id: generateUlid(), ...w }));
|
||
return (trx || db)('wallets').insert(withIds).returning('*');
|
||
},
|
||
};
|