@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.
- package/dist/billing/crypto/charge-store.d.ts +10 -0
- package/dist/billing/crypto/charge-store.js +9 -1
- package/dist/billing/crypto/payment-method-store.d.ts +2 -0
- package/dist/billing/crypto/payment-method-store.js +6 -0
- package/dist/db/schema/crypto.d.ts +34 -0
- package/dist/db/schema/crypto.js +3 -1
- package/drizzle/migrations/0010_oracle_address.sql +11 -0
- package/drizzle/migrations/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/src/billing/crypto/charge-store.ts +14 -1
- package/src/billing/crypto/payment-method-store.ts +8 -0
- package/src/db/schema/crypto.ts +3 -1
|
@@ -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
|
|
@@ -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";
|
package/dist/db/schema/crypto.js
CHANGED
|
@@ -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"), //
|
|
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';
|
package/package.json
CHANGED
|
@@ -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
|
}
|
package/src/db/schema/crypto.ts
CHANGED
|
@@ -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"), //
|
|
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
|
});
|