@wopr-network/platform-core 1.27.1 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,11 @@ export interface ICryptoChargeRepository {
33
33
  createStablecoinCharge(input: CryptoDepositChargeInput): Promise<void>;
34
34
  getByDepositAddress(address: string): Promise<CryptoChargeRecord | null>;
35
35
  getNextDerivationIndex(): Promise<number>;
36
+ /** List deposit addresses with pending (uncredited) charges, grouped by chain. */
37
+ listActiveDepositAddresses(): Promise<{
38
+ chain: string;
39
+ address: string;
40
+ }[]>;
36
41
  }
37
42
  /**
38
43
  * Manages crypto charge records in PostgreSQL.
@@ -62,6 +67,11 @@ export declare class DrizzleCryptoChargeRepository implements ICryptoChargeRepos
62
67
  createStablecoinCharge(input: CryptoDepositChargeInput): Promise<void>;
63
68
  /** Look up a charge by its deposit address. */
64
69
  getByDepositAddress(address: string): Promise<CryptoChargeRecord | null>;
70
+ /** List deposit addresses with pending (uncredited) charges. */
71
+ listActiveDepositAddresses(): Promise<{
72
+ chain: string;
73
+ address: string;
74
+ }[]>;
65
75
  /** Get the next available HD derivation index (max + 1, or 0 if empty). */
66
76
  getNextDerivationIndex(): Promise<number>;
67
77
  }
@@ -1,4 +1,4 @@
1
- import { eq, sql } from "drizzle-orm";
1
+ import { and, eq, isNotNull, isNull, sql } from "drizzle-orm";
2
2
  import { cryptoCharges } from "../../db/schema/crypto.js";
3
3
  /**
4
4
  * Manages crypto charge records in PostgreSQL.
@@ -98,6 +98,14 @@ export class DrizzleCryptoChargeRepository {
98
98
  return null;
99
99
  return this.toRecord(row);
100
100
  }
101
+ /** List deposit addresses with pending (uncredited) charges. */
102
+ async listActiveDepositAddresses() {
103
+ const rows = await this.db
104
+ .select({ chain: cryptoCharges.chain, address: cryptoCharges.depositAddress })
105
+ .from(cryptoCharges)
106
+ .where(and(isNull(cryptoCharges.creditedAt), isNotNull(cryptoCharges.depositAddress), isNotNull(cryptoCharges.chain)));
107
+ return rows.filter((r) => r.chain !== null && r.address !== null);
108
+ }
101
109
  /** Get the next available HD derivation index (max + 1, or 0 if empty). */
102
110
  async getNextDerivationIndex() {
103
111
  const result = await this.db
@@ -10,6 +10,8 @@ export interface PaymentMethodRecord {
10
10
  enabled: boolean;
11
11
  displayOrder: number;
12
12
  rpcUrl: string | null;
13
+ oracleAddress: string | null;
14
+ xpub: string | null;
13
15
  confirmations: number;
14
16
  }
15
17
  export interface IPaymentMethodStore {
@@ -43,6 +43,8 @@ export class DrizzlePaymentMethodStore {
43
43
  enabled: method.enabled,
44
44
  displayOrder: method.displayOrder,
45
45
  rpcUrl: method.rpcUrl,
46
+ oracleAddress: method.oracleAddress,
47
+ xpub: method.xpub,
46
48
  confirmations: method.confirmations,
47
49
  })
48
50
  .onConflictDoUpdate({
@@ -57,6 +59,8 @@ export class DrizzlePaymentMethodStore {
57
59
  enabled: method.enabled,
58
60
  displayOrder: method.displayOrder,
59
61
  rpcUrl: method.rpcUrl,
62
+ oracleAddress: method.oracleAddress,
63
+ xpub: method.xpub,
60
64
  confirmations: method.confirmations,
61
65
  },
62
66
  });
@@ -77,6 +81,8 @@ function toRecord(row) {
77
81
  enabled: row.enabled,
78
82
  displayOrder: row.displayOrder,
79
83
  rpcUrl: row.rpcUrl,
84
+ oracleAddress: row.oracleAddress,
85
+ xpub: row.xpub,
80
86
  confirmations: row.confirmations,
81
87
  };
82
88
  }
@@ -475,6 +475,40 @@ export declare const paymentMethods: import("drizzle-orm/pg-core").PgTableWithCo
475
475
  identity: undefined;
476
476
  generated: undefined;
477
477
  }, {}, {}>;
478
+ oracleAddress: import("drizzle-orm/pg-core").PgColumn<{
479
+ name: "oracle_address";
480
+ tableName: "payment_methods";
481
+ dataType: "string";
482
+ columnType: "PgText";
483
+ data: string;
484
+ driverParam: string;
485
+ notNull: false;
486
+ hasDefault: false;
487
+ isPrimaryKey: false;
488
+ isAutoincrement: false;
489
+ hasRuntimeDefault: false;
490
+ enumValues: [string, ...string[]];
491
+ baseColumn: never;
492
+ identity: undefined;
493
+ generated: undefined;
494
+ }, {}, {}>;
495
+ xpub: import("drizzle-orm/pg-core").PgColumn<{
496
+ name: "xpub";
497
+ tableName: "payment_methods";
498
+ dataType: "string";
499
+ columnType: "PgText";
500
+ data: string;
501
+ driverParam: string;
502
+ notNull: false;
503
+ hasDefault: false;
504
+ isPrimaryKey: false;
505
+ isAutoincrement: false;
506
+ hasRuntimeDefault: false;
507
+ enumValues: [string, ...string[]];
508
+ baseColumn: never;
509
+ identity: undefined;
510
+ generated: undefined;
511
+ }, {}, {}>;
478
512
  confirmations: import("drizzle-orm/pg-core").PgColumn<{
479
513
  name: "confirmations";
480
514
  tableName: "payment_methods";
@@ -54,7 +54,9 @@ export const paymentMethods = pgTable("payment_methods", {
54
54
  displayName: text("display_name").notNull(),
55
55
  enabled: boolean("enabled").notNull().default(true),
56
56
  displayOrder: integer("display_order").notNull().default(0),
57
- rpcUrl: text("rpc_url"), // override per-chain RPC (null = use default)
57
+ rpcUrl: text("rpc_url"), // chain node RPC endpoint
58
+ oracleAddress: text("oracle_address"), // Chainlink feed address for price (null = 1:1 stablecoin)
59
+ xpub: text("xpub"), // HD wallet extended public key for deposit address derivation
58
60
  confirmations: integer("confirmations").notNull().default(1),
59
61
  createdAt: text("created_at").notNull().default(sql `(now())`),
60
62
  });
@@ -0,0 +1,11 @@
1
+ ALTER TABLE "payment_methods" ADD COLUMN "oracle_address" text;
2
+ --> statement-breakpoint
3
+ ALTER TABLE "payment_methods" ADD COLUMN "xpub" text;
4
+ --> statement-breakpoint
5
+ UPDATE "payment_methods" SET "oracle_address" = '0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70' WHERE "id" = 'ETH:base';
6
+ --> statement-breakpoint
7
+ UPDATE "payment_methods" SET "oracle_address" = '0x64c911996D3c6aC71f9b455B1E8E7266BcbD848F' WHERE "id" = 'BTC:mainnet';
8
+ --> statement-breakpoint
9
+ UPDATE "payment_methods" SET "xpub" = 'xpub6DSVkV7mgEZrnBEmZEq412Cx9sYYZtFvGSb6W9bRDDSikYdpmUiJoNeuechuir63ZjdHQuWBLwchQQnh2GD6DJP6bPKUa1bey1X6XvH9jvM' WHERE "chain" = 'base';
10
+ --> statement-breakpoint
11
+ UPDATE "payment_methods" SET "xpub" = 'xpub6BuGg4sQuvoA7q545ZoStxU7QP24qmZNMo39FxRjLwbBCQ77sjsHGcpxeNVboGZQNdbeANHVK1GJx7ECMfjohkpLqoGLVP9SCQM4bR1F5vh' WHERE "chain" = 'bitcoin';
@@ -71,6 +71,13 @@
71
71
  "when": 1742400000000,
72
72
  "tag": "0009_tenant_update_configs",
73
73
  "breakpoints": true
74
+ },
75
+ {
76
+ "idx": 10,
77
+ "version": "7",
78
+ "when": 1742486400000,
79
+ "tag": "0010_oracle_address",
80
+ "breakpoints": true
74
81
  }
75
82
  ]
76
83
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wopr-network/platform-core",
3
- "version": "1.27.1",
3
+ "version": "1.28.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { eq, sql } from "drizzle-orm";
1
+ import { and, eq, isNotNull, isNull, sql } from "drizzle-orm";
2
2
  import type { PlatformDb } from "../../db/index.js";
3
3
  import { cryptoCharges } from "../../db/schema/crypto.js";
4
4
  import type { CryptoPaymentState } from "./types.js";
@@ -43,6 +43,8 @@ export interface ICryptoChargeRepository {
43
43
  createStablecoinCharge(input: CryptoDepositChargeInput): Promise<void>;
44
44
  getByDepositAddress(address: string): Promise<CryptoChargeRecord | null>;
45
45
  getNextDerivationIndex(): Promise<number>;
46
+ /** List deposit addresses with pending (uncredited) charges, grouped by chain. */
47
+ listActiveDepositAddresses(): Promise<{ chain: string; address: string }[]>;
46
48
  }
47
49
 
48
50
  /**
@@ -154,6 +156,17 @@ export class DrizzleCryptoChargeRepository implements ICryptoChargeRepository {
154
156
  return this.toRecord(row);
155
157
  }
156
158
 
159
+ /** List deposit addresses with pending (uncredited) charges. */
160
+ async listActiveDepositAddresses(): Promise<{ chain: string; address: string }[]> {
161
+ const rows = await this.db
162
+ .select({ chain: cryptoCharges.chain, address: cryptoCharges.depositAddress })
163
+ .from(cryptoCharges)
164
+ .where(
165
+ and(isNull(cryptoCharges.creditedAt), isNotNull(cryptoCharges.depositAddress), isNotNull(cryptoCharges.chain)),
166
+ );
167
+ return rows.filter((r): r is { chain: string; address: string } => r.chain !== null && r.address !== null);
168
+ }
169
+
157
170
  /** Get the next available HD derivation index (max + 1, or 0 if empty). */
158
171
  async getNextDerivationIndex(): Promise<number> {
159
172
  const result = await this.db
@@ -13,6 +13,8 @@ export interface PaymentMethodRecord {
13
13
  enabled: boolean;
14
14
  displayOrder: number;
15
15
  rpcUrl: string | null;
16
+ oracleAddress: string | null;
17
+ xpub: string | null;
16
18
  confirmations: number;
17
19
  }
18
20
 
@@ -76,6 +78,8 @@ export class DrizzlePaymentMethodStore implements IPaymentMethodStore {
76
78
  enabled: method.enabled,
77
79
  displayOrder: method.displayOrder,
78
80
  rpcUrl: method.rpcUrl,
81
+ oracleAddress: method.oracleAddress,
82
+ xpub: method.xpub,
79
83
  confirmations: method.confirmations,
80
84
  })
81
85
  .onConflictDoUpdate({
@@ -90,6 +94,8 @@ export class DrizzlePaymentMethodStore implements IPaymentMethodStore {
90
94
  enabled: method.enabled,
91
95
  displayOrder: method.displayOrder,
92
96
  rpcUrl: method.rpcUrl,
97
+ oracleAddress: method.oracleAddress,
98
+ xpub: method.xpub,
93
99
  confirmations: method.confirmations,
94
100
  },
95
101
  });
@@ -112,6 +118,8 @@ function toRecord(row: typeof paymentMethods.$inferSelect): PaymentMethodRecord
112
118
  enabled: row.enabled,
113
119
  displayOrder: row.displayOrder,
114
120
  rpcUrl: row.rpcUrl,
121
+ oracleAddress: row.oracleAddress,
122
+ xpub: row.xpub,
115
123
  confirmations: row.confirmations,
116
124
  };
117
125
  }
@@ -61,7 +61,9 @@ export const paymentMethods = pgTable("payment_methods", {
61
61
  displayName: text("display_name").notNull(),
62
62
  enabled: boolean("enabled").notNull().default(true),
63
63
  displayOrder: integer("display_order").notNull().default(0),
64
- rpcUrl: text("rpc_url"), // override per-chain RPC (null = use default)
64
+ rpcUrl: text("rpc_url"), // chain node RPC endpoint
65
+ oracleAddress: text("oracle_address"), // Chainlink feed address for price (null = 1:1 stablecoin)
66
+ xpub: text("xpub"), // HD wallet extended public key for deposit address derivation
65
67
  confirmations: integer("confirmations").notNull().default(1),
66
68
  createdAt: text("created_at").notNull().default(sql`(now())`),
67
69
  });