feat: payments schema + deps for Lightning ranked fights
Add payments and wallet_connections tables, new columns on fights (mode, pot_sats, payout_status) and bots (sats_won, sats_wagered, has_wallet). Install nostr-tools and @cashu/cashu-ts for NWC + ecash support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
6b139a076a
commit
e92f483e66
Generated
+84
@@ -54,6 +54,9 @@ importers:
|
||||
|
||||
server:
|
||||
dependencies:
|
||||
'@cashu/cashu-ts':
|
||||
specifier: ^3.5.0
|
||||
version: 3.5.0
|
||||
'@hono/node-server':
|
||||
specifier: ^1.14.1
|
||||
version: 1.19.11(hono@4.12.5)
|
||||
@@ -72,6 +75,9 @@ importers:
|
||||
nanoid:
|
||||
specifier: ^5.1.5
|
||||
version: 5.1.6
|
||||
nostr-tools:
|
||||
specifier: ^2.23.3
|
||||
version: 2.23.3(typescript@5.9.3)
|
||||
devDependencies:
|
||||
'@types/better-sqlite3':
|
||||
specifier: ^7.6.13
|
||||
@@ -592,6 +598,10 @@ packages:
|
||||
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@cashu/cashu-ts@3.5.0':
|
||||
resolution: {integrity: sha512-LVOfCY1ZjQ+/f/CwekCeH+QRjN9SaHp8rTUjf8f4feHxT9Bqn/Bw+qYfNhaBKLWrqS19DMK/q/ern3AQ2MCq9w==}
|
||||
engines: {node: '>=22.4.0'}
|
||||
|
||||
'@drizzle-team/brocli@0.10.2':
|
||||
resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
|
||||
|
||||
@@ -1058,6 +1068,18 @@ packages:
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||
|
||||
'@noble/ciphers@2.1.1':
|
||||
resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
'@noble/curves@2.0.1':
|
||||
resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
'@noble/hashes@2.0.1':
|
||||
resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
'@petamoriken/float16@3.9.3':
|
||||
resolution: {integrity: sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g==}
|
||||
|
||||
@@ -1248,6 +1270,15 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@scure/base@2.0.0':
|
||||
resolution: {integrity: sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==}
|
||||
|
||||
'@scure/bip32@2.0.1':
|
||||
resolution: {integrity: sha512-4Md1NI5BzoVP+bhyJaY3K6yMesEFzNS1sE/cP+9nuvE7p/b0kx9XbpDHHFl8dHtufcbdHRUUQdRqLIPHN/s7yA==}
|
||||
|
||||
'@scure/bip39@2.0.1':
|
||||
resolution: {integrity: sha512-PsxdFj/d2AcJcZDX1FXN3dDgitDDTmwf78rKZq1a6c1P1Nan1X/Sxc7667zU3U+AN60g7SxxP0YCVw2H/hBycg==}
|
||||
|
||||
'@surma/rollup-plugin-off-main-thread@2.2.3':
|
||||
resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==}
|
||||
|
||||
@@ -2367,6 +2398,17 @@ packages:
|
||||
node-releases@2.0.36:
|
||||
resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==}
|
||||
|
||||
nostr-tools@2.23.3:
|
||||
resolution: {integrity: sha512-AALyt9k8xPdF4UV2mlLJ2mgCn4kpTB0DZ8t2r6wjdUh6anfx2cTVBsHUlo9U0EY/cKC5wcNyiMAmRJV5OVEalA==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.0.0'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
nostr-wasm@0.1.0:
|
||||
resolution: {integrity: sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==}
|
||||
|
||||
object-inspect@1.13.4:
|
||||
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -3698,6 +3740,13 @@ snapshots:
|
||||
'@babel/helper-string-parser': 7.27.1
|
||||
'@babel/helper-validator-identifier': 7.28.5
|
||||
|
||||
'@cashu/cashu-ts@3.5.0':
|
||||
dependencies:
|
||||
'@noble/curves': 2.0.1
|
||||
'@noble/hashes': 2.0.1
|
||||
'@scure/base': 2.0.0
|
||||
'@scure/bip32': 2.0.1
|
||||
|
||||
'@drizzle-team/brocli@0.10.2': {}
|
||||
|
||||
'@esbuild-kit/core-utils@3.3.2':
|
||||
@@ -3953,6 +4002,14 @@ snapshots:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
'@noble/ciphers@2.1.1': {}
|
||||
|
||||
'@noble/curves@2.0.1':
|
||||
dependencies:
|
||||
'@noble/hashes': 2.0.1
|
||||
|
||||
'@noble/hashes@2.0.1': {}
|
||||
|
||||
'@petamoriken/float16@3.9.3': {}
|
||||
|
||||
'@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(rollup@2.80.0)':
|
||||
@@ -4078,6 +4135,19 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc@4.59.0':
|
||||
optional: true
|
||||
|
||||
'@scure/base@2.0.0': {}
|
||||
|
||||
'@scure/bip32@2.0.1':
|
||||
dependencies:
|
||||
'@noble/curves': 2.0.1
|
||||
'@noble/hashes': 2.0.1
|
||||
'@scure/base': 2.0.0
|
||||
|
||||
'@scure/bip39@2.0.1':
|
||||
dependencies:
|
||||
'@noble/hashes': 2.0.1
|
||||
'@scure/base': 2.0.0
|
||||
|
||||
'@surma/rollup-plugin-off-main-thread@2.2.3':
|
||||
dependencies:
|
||||
ejs: 3.1.10
|
||||
@@ -5196,6 +5266,20 @@ snapshots:
|
||||
|
||||
node-releases@2.0.36: {}
|
||||
|
||||
nostr-tools@2.23.3(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@noble/ciphers': 2.1.1
|
||||
'@noble/curves': 2.0.1
|
||||
'@noble/hashes': 2.0.1
|
||||
'@scure/base': 2.0.0
|
||||
'@scure/bip32': 2.0.1
|
||||
'@scure/bip39': 2.0.1
|
||||
nostr-wasm: 0.1.0
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
nostr-wasm@0.1.0: {}
|
||||
|
||||
object-inspect@1.13.4: {}
|
||||
|
||||
object-keys@1.1.1: {}
|
||||
|
||||
+3
-1
@@ -11,12 +11,14 @@
|
||||
"migrate": "tsx src/db/migrate.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cashu/cashu-ts": "^3.5.0",
|
||||
"@hono/node-server": "^1.14.1",
|
||||
"better-sqlite3": "^11.9.1",
|
||||
"chalk": "^5.6.2",
|
||||
"drizzle-orm": "^0.40.1",
|
||||
"hono": "^4.7.6",
|
||||
"nanoid": "^5.1.5"
|
||||
"nanoid": "^5.1.5",
|
||||
"nostr-tools": "^2.23.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
|
||||
@@ -20,6 +20,9 @@ export const bots = sqliteTable('bots', {
|
||||
consecutiveErrors: integer('consecutive_errors').notNull().default(0),
|
||||
lastErrorAt: text('last_error_at'),
|
||||
customization: text('customization'),
|
||||
satsWon: integer('sats_won').notNull().default(0),
|
||||
satsWagered: integer('sats_wagered').notNull().default(0),
|
||||
hasWallet: integer('has_wallet', { mode: 'boolean' }).notNull().default(false),
|
||||
createdAt: text('created_at').notNull(),
|
||||
})
|
||||
|
||||
@@ -36,6 +39,9 @@ export const fights = sqliteTable('fights', {
|
||||
scheduledAt: text('scheduled_at'),
|
||||
startedAt: text('started_at'),
|
||||
endedAt: text('ended_at'),
|
||||
mode: text('mode', { enum: ['free', 'ranked'] }).notNull().default('free'),
|
||||
potSats: integer('pot_sats').notNull().default(0),
|
||||
payoutStatus: text('payout_status', { enum: ['pending', 'paid', 'failed'] }),
|
||||
createdAt: text('created_at').notNull(),
|
||||
})
|
||||
|
||||
@@ -56,6 +62,34 @@ export const rounds = sqliteTable('rounds', {
|
||||
createdAt: text('created_at').notNull(),
|
||||
})
|
||||
|
||||
export const payments = sqliteTable('payments', {
|
||||
id: text('id').primaryKey(),
|
||||
fightId: text('fight_id').references(() => fights.id),
|
||||
botId: text('bot_id').notNull().references(() => bots.id),
|
||||
direction: text('direction', { enum: ['in', 'out'] }).notNull(),
|
||||
amountSats: integer('amount_sats').notNull(),
|
||||
method: text('method', { enum: ['lightning', 'cashu'] }).notNull(),
|
||||
status: text('status', {
|
||||
enum: ['pending', 'confirmed', 'failed', 'refunded'],
|
||||
}).notNull().default('pending'),
|
||||
invoice: text('invoice'),
|
||||
preimage: text('preimage'),
|
||||
cashuToken: text('cashu_token'),
|
||||
errorReason: text('error_reason'),
|
||||
createdAt: text('created_at').notNull(),
|
||||
confirmedAt: text('confirmed_at'),
|
||||
refundedAt: text('refunded_at'),
|
||||
})
|
||||
|
||||
export const walletConnections = sqliteTable('wallet_connections', {
|
||||
id: text('id').primaryKey(),
|
||||
botId: text('bot_id').notNull().unique().references(() => bots.id),
|
||||
method: text('method', { enum: ['nwc', 'lnaddress', 'cashu_mint'] }).notNull(),
|
||||
connectionData: text('connection_data').notNull(),
|
||||
createdAt: text('created_at').notNull(),
|
||||
lastUsedAt: text('last_used_at'),
|
||||
})
|
||||
|
||||
export const bets = sqliteTable('bets', {
|
||||
id: text('id').primaryKey(),
|
||||
fightId: text('fight_id').notNull().references(() => fights.id),
|
||||
|
||||
@@ -58,6 +58,34 @@ export function runMigrations() {
|
||||
);
|
||||
`)
|
||||
|
||||
sqlite.exec(`
|
||||
CREATE TABLE IF NOT EXISTS payments (
|
||||
id TEXT PRIMARY KEY,
|
||||
fight_id TEXT REFERENCES fights(id),
|
||||
bot_id TEXT NOT NULL REFERENCES bots(id),
|
||||
direction TEXT NOT NULL,
|
||||
amount_sats INTEGER NOT NULL,
|
||||
method TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
invoice TEXT,
|
||||
preimage TEXT,
|
||||
cashu_token TEXT,
|
||||
error_reason TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
confirmed_at TEXT,
|
||||
refunded_at TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS wallet_connections (
|
||||
id TEXT PRIMARY KEY,
|
||||
bot_id TEXT NOT NULL UNIQUE REFERENCES bots(id),
|
||||
method TEXT NOT NULL,
|
||||
connection_data TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
last_used_at TEXT
|
||||
);
|
||||
`)
|
||||
|
||||
// Column migrations for existing databases
|
||||
const migrations = [
|
||||
"ALTER TABLE bots ADD COLUMN archetype TEXT NOT NULL DEFAULT 'standard'",
|
||||
@@ -66,6 +94,14 @@ export function runMigrations() {
|
||||
"ALTER TABLE bots ADD COLUMN consecutive_errors INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE bots ADD COLUMN last_error_at TEXT",
|
||||
"ALTER TABLE bots ADD COLUMN customization TEXT",
|
||||
// Ranked fights columns
|
||||
"ALTER TABLE fights ADD COLUMN mode TEXT NOT NULL DEFAULT 'free'",
|
||||
"ALTER TABLE fights ADD COLUMN pot_sats INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE fights ADD COLUMN payout_status TEXT",
|
||||
// Bot sats tracking
|
||||
"ALTER TABLE bots ADD COLUMN sats_won INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE bots ADD COLUMN sats_wagered INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE bots ADD COLUMN has_wallet INTEGER NOT NULL DEFAULT 0",
|
||||
]
|
||||
|
||||
for (const sql of migrations) {
|
||||
|
||||
Reference in New Issue
Block a user