@nestjs-dash/wallet 0.1.1

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.
Files changed (81) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +95 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/entities/transaction.entity.d.ts +18 -0
  6. package/dist/entities/transaction.entity.d.ts.map +1 -0
  7. package/dist/entities/transaction.entity.js +68 -0
  8. package/dist/entities/transaction.entity.js.map +1 -0
  9. package/dist/entities/transfer.entity.d.ts +23 -0
  10. package/dist/entities/transfer.entity.d.ts.map +1 -0
  11. package/dist/entities/transfer.entity.js +97 -0
  12. package/dist/entities/transfer.entity.js.map +1 -0
  13. package/dist/entities/wallet.entity.d.ts +16 -0
  14. package/dist/entities/wallet.entity.d.ts.map +1 -0
  15. package/dist/entities/wallet.entity.js +67 -0
  16. package/dist/entities/wallet.entity.js.map +1 -0
  17. package/dist/errors.d.ts +13 -0
  18. package/dist/errors.d.ts.map +1 -0
  19. package/dist/errors.js +25 -0
  20. package/dist/errors.js.map +1 -0
  21. package/dist/events/wallet-event.publisher.d.ts +12 -0
  22. package/dist/events/wallet-event.publisher.d.ts.map +1 -0
  23. package/dist/events/wallet-event.publisher.js +44 -0
  24. package/dist/events/wallet-event.publisher.js.map +1 -0
  25. package/dist/events/wallet.events.d.ts +22 -0
  26. package/dist/events/wallet.events.d.ts.map +1 -0
  27. package/dist/events/wallet.events.js +2 -0
  28. package/dist/events/wallet.events.js.map +1 -0
  29. package/dist/exchange.service.d.ts +17 -0
  30. package/dist/exchange.service.d.ts.map +1 -0
  31. package/dist/exchange.service.js +70 -0
  32. package/dist/exchange.service.js.map +1 -0
  33. package/dist/float-wallet.service.d.ts +11 -0
  34. package/dist/float-wallet.service.d.ts.map +1 -0
  35. package/dist/float-wallet.service.js +33 -0
  36. package/dist/float-wallet.service.js.map +1 -0
  37. package/dist/index.d.ts +20 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +18 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/lock/array-lock.service.d.ts +8 -0
  42. package/dist/lock/array-lock.service.d.ts.map +1 -0
  43. package/dist/lock/array-lock.service.js +60 -0
  44. package/dist/lock/array-lock.service.js.map +1 -0
  45. package/dist/lock/lock.service.d.ts +5 -0
  46. package/dist/lock/lock.service.d.ts.map +1 -0
  47. package/dist/lock/lock.service.js +4 -0
  48. package/dist/lock/lock.service.js.map +1 -0
  49. package/dist/lock/memcached-lock.service.d.ts +21 -0
  50. package/dist/lock/memcached-lock.service.d.ts.map +1 -0
  51. package/dist/lock/memcached-lock.service.js +45 -0
  52. package/dist/lock/memcached-lock.service.js.map +1 -0
  53. package/dist/lock/redis-lock.service.d.ts +13 -0
  54. package/dist/lock/redis-lock.service.d.ts.map +1 -0
  55. package/dist/lock/redis-lock.service.js +43 -0
  56. package/dist/lock/redis-lock.service.js.map +1 -0
  57. package/dist/migrations/generate.d.ts +22 -0
  58. package/dist/migrations/generate.d.ts.map +1 -0
  59. package/dist/migrations/generate.js +226 -0
  60. package/dist/migrations/generate.js.map +1 -0
  61. package/dist/tokens.d.ts +56 -0
  62. package/dist/tokens.d.ts.map +1 -0
  63. package/dist/tokens.js +13 -0
  64. package/dist/tokens.js.map +1 -0
  65. package/dist/transfer.service.d.ts +29 -0
  66. package/dist/transfer.service.d.ts.map +1 -0
  67. package/dist/transfer.service.js +154 -0
  68. package/dist/transfer.service.js.map +1 -0
  69. package/dist/wallet.module.d.ts +12 -0
  70. package/dist/wallet.module.d.ts.map +1 -0
  71. package/dist/wallet.module.js +150 -0
  72. package/dist/wallet.module.js.map +1 -0
  73. package/dist/wallet.service.d.ts +39 -0
  74. package/dist/wallet.service.d.ts.map +1 -0
  75. package/dist/wallet.service.js +230 -0
  76. package/dist/wallet.service.js.map +1 -0
  77. package/dist/warmup.service.d.ts +13 -0
  78. package/dist/warmup.service.d.ts.map +1 -0
  79. package/dist/warmup.service.js +76 -0
  80. package/dist/warmup.service.js.map +1 -0
  81. package/package.json +69 -0
@@ -0,0 +1,150 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var WalletModule_1;
8
+ import { Module } from '@nestjs/common';
9
+ import { EventEmitterModule } from '@nestjs/event-emitter';
10
+ import { getRepositoryToken } from '@nestjs/typeorm';
11
+ import { TransactionEntity } from './entities/transaction.entity.js';
12
+ import { TransferEntity } from './entities/transfer.entity.js';
13
+ import { WalletEntity } from './entities/wallet.entity.js';
14
+ import { WalletEventPublisher } from './events/wallet-event.publisher.js';
15
+ import { ExchangeService } from './exchange.service.js';
16
+ import { FloatWalletService } from './float-wallet.service.js';
17
+ import { ArrayLockService } from './lock/array-lock.service.js';
18
+ import { MemcachedLockService } from './lock/memcached-lock.service.js';
19
+ import { RedisLockService } from './lock/redis-lock.service.js';
20
+ import { DEFAULT_LOCK_TTL_MS, DEFAULT_WALLET_NAME, DEFAULT_WALLET_SLUG, WALLET_DATA_SOURCE, WALLET_LOCK, WALLET_OPTIONS, } from './tokens.js';
21
+ import { TransferService } from './transfer.service.js';
22
+ import { WalletService } from './wallet.service.js';
23
+ import { WarmupService } from './warmup.service.js';
24
+ async function createLockProvider(options) {
25
+ const driver = options.lock?.driver ?? 'array';
26
+ if (driver === 'redis') {
27
+ const service = await RedisLockService.create(options.lock?.redis?.url);
28
+ return { provide: WALLET_LOCK, useValue: service };
29
+ }
30
+ if (driver === 'memcached') {
31
+ const service = await MemcachedLockService.create(options.lock?.memcached?.servers);
32
+ return { provide: WALLET_LOCK, useValue: service };
33
+ }
34
+ return { provide: WALLET_LOCK, useValue: new ArrayLockService() };
35
+ }
36
+ function resolveOptions(options) {
37
+ return {
38
+ dataSource: options.dataSource,
39
+ defaultWalletSlug: options.defaultWalletSlug ?? DEFAULT_WALLET_SLUG,
40
+ defaultWalletName: options.defaultWalletName ?? DEFAULT_WALLET_NAME,
41
+ holderIdType: options.holderIdType ?? 'int',
42
+ events: { enabled: options.events?.enabled !== false },
43
+ exchange: options.exchange,
44
+ lock: {
45
+ driver: options.lock?.driver ?? 'array',
46
+ ttlMs: options.lock?.ttlMs ?? DEFAULT_LOCK_TTL_MS,
47
+ redis: options.lock?.redis,
48
+ memcached: options.lock?.memcached,
49
+ },
50
+ tables: options.tables,
51
+ };
52
+ }
53
+ function requireDataSource(options) {
54
+ if (!options.dataSource) {
55
+ throw new Error('WalletModule requires options.dataSource. Use WalletModule.forRootAsync({ inject: [DataSource], useFactory: (dataSource) => ({ dataSource, ... }) }) so the host app DataSource is bridged (pnpm may install multiple typeorm copies).');
56
+ }
57
+ return options.dataSource;
58
+ }
59
+ function repositoryFactory(entity) {
60
+ return (dataSource) => dataSource.getRepository(entity);
61
+ }
62
+ function buildProviders(optionsProvider) {
63
+ return [
64
+ optionsProvider,
65
+ {
66
+ provide: WALLET_DATA_SOURCE,
67
+ useFactory: (options) => requireDataSource(options),
68
+ inject: [WALLET_OPTIONS],
69
+ },
70
+ {
71
+ provide: getRepositoryToken(WalletEntity),
72
+ useFactory: repositoryFactory(WalletEntity),
73
+ inject: [WALLET_DATA_SOURCE],
74
+ },
75
+ {
76
+ provide: getRepositoryToken(TransactionEntity),
77
+ useFactory: repositoryFactory(TransactionEntity),
78
+ inject: [WALLET_DATA_SOURCE],
79
+ },
80
+ {
81
+ provide: getRepositoryToken(TransferEntity),
82
+ useFactory: repositoryFactory(TransferEntity),
83
+ inject: [WALLET_DATA_SOURCE],
84
+ },
85
+ {
86
+ provide: WALLET_LOCK,
87
+ useFactory: async (options) => {
88
+ const provider = await createLockProvider(options);
89
+ return provider.useValue;
90
+ },
91
+ inject: [WALLET_OPTIONS],
92
+ },
93
+ WalletEventPublisher,
94
+ WalletService,
95
+ FloatWalletService,
96
+ TransferService,
97
+ ExchangeService,
98
+ WarmupService,
99
+ ];
100
+ }
101
+ const exportedProviders = [
102
+ WalletService,
103
+ FloatWalletService,
104
+ TransferService,
105
+ ExchangeService,
106
+ WarmupService,
107
+ WALLET_OPTIONS,
108
+ WALLET_LOCK,
109
+ WALLET_DATA_SOURCE,
110
+ getRepositoryToken(WalletEntity),
111
+ getRepositoryToken(TransactionEntity),
112
+ getRepositoryToken(TransferEntity),
113
+ ];
114
+ let WalletModule = WalletModule_1 = class WalletModule {
115
+ static forRoot(options = {}) {
116
+ const resolved = resolveOptions(options);
117
+ const imports = [];
118
+ if (resolved.events?.enabled !== false) {
119
+ imports.push(EventEmitterModule.forRoot());
120
+ }
121
+ return {
122
+ module: WalletModule_1,
123
+ global: true,
124
+ imports,
125
+ providers: buildProviders({ provide: WALLET_OPTIONS, useValue: resolved }),
126
+ exports: exportedProviders,
127
+ };
128
+ }
129
+ static forRootAsync(options) {
130
+ const imports = [...(options.imports ?? [])];
131
+ imports.push(EventEmitterModule.forRoot());
132
+ return {
133
+ module: WalletModule_1,
134
+ global: true,
135
+ imports,
136
+ providers: buildProviders({
137
+ provide: WALLET_OPTIONS,
138
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
139
+ useFactory: async (...args) => resolveOptions(await options.useFactory(...args)),
140
+ inject: options.inject ?? [],
141
+ }),
142
+ exports: exportedProviders,
143
+ };
144
+ }
145
+ };
146
+ WalletModule = WalletModule_1 = __decorate([
147
+ Module({})
148
+ ], WalletModule);
149
+ export { WalletModule };
150
+ //# sourceMappingURL=wallet.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.module.js","sourceRoot":"","sources":["../src/wallet.module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { DataSource, Repository } from 'typeorm';
2
+ import { TransactionEntity } from './entities/transaction.entity.js';
3
+ import { WalletEntity } from './entities/wallet.entity.js';
4
+ import { WalletEventPublisher } from './events/wallet-event.publisher.js';
5
+ import { type WalletLockService } from './lock/lock.service.js';
6
+ import { type HolderId, type WalletModuleOptions } from './tokens.js';
7
+ export interface CreateWalletInput {
8
+ name?: string;
9
+ slug?: string;
10
+ description?: string | null;
11
+ meta?: Record<string, unknown> | null;
12
+ decimalPlaces?: number;
13
+ }
14
+ export declare class WalletService {
15
+ private readonly wallets;
16
+ private readonly transactions;
17
+ private readonly dataSource;
18
+ private readonly lockService;
19
+ private readonly events;
20
+ private readonly defaultSlug;
21
+ private readonly defaultName;
22
+ private readonly lockTtlMs;
23
+ constructor(wallets: Repository<WalletEntity>, transactions: Repository<TransactionEntity>, dataSource: DataSource, options: WalletModuleOptions, lockService: WalletLockService, events: WalletEventPublisher);
24
+ private normalizeHolderId;
25
+ createWallet(holderType: string, holderId: HolderId, input?: CreateWalletInput): Promise<WalletEntity>;
26
+ hasWallet(holderType: string, holderId: HolderId, slug?: string): Promise<boolean>;
27
+ getWallet(holderType: string, holderId: HolderId, slug?: string): Promise<WalletEntity | null>;
28
+ getWalletOrFail(holderType: string, holderId: HolderId, slug?: string): Promise<WalletEntity>;
29
+ getOrCreateWallet(holderType: string, holderId: HolderId, input?: CreateWalletInput): Promise<WalletEntity>;
30
+ getWalletById(walletId: number): Promise<WalletEntity>;
31
+ balance(wallet: WalletEntity): string;
32
+ balanceInt(wallet: WalletEntity): number;
33
+ deposit(wallet: WalletEntity, amount: number | string, meta?: Record<string, unknown> | null): Promise<TransactionEntity>;
34
+ withdraw(wallet: WalletEntity, amount: number | string, meta?: Record<string, unknown> | null): Promise<TransactionEntity>;
35
+ normalizeAmount(amount: number | string): bigint;
36
+ floatToInt(amount: number, decimalPlaces: number): bigint;
37
+ intToFloat(amount: string | number | bigint, decimalPlaces: number): number;
38
+ }
39
+ //# sourceMappingURL=wallet.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.service.d.ts","sourceRoot":"","sources":["../src/wallet.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,230 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Inject, Injectable } from '@nestjs/common';
14
+ import { InjectRepository } from '@nestjs/typeorm';
15
+ import { randomUUID } from 'node:crypto';
16
+ import { DataSource, Repository } from 'typeorm';
17
+ import { TransactionEntity } from './entities/transaction.entity.js';
18
+ import { WalletEntity } from './entities/wallet.entity.js';
19
+ import { InsufficientFundsError, WalletNotFoundError } from './errors.js';
20
+ import { WalletEventPublisher } from './events/wallet-event.publisher.js';
21
+ import { walletLockKey } from './lock/lock.service.js';
22
+ import { DEFAULT_LOCK_TTL_MS, DEFAULT_WALLET_NAME, DEFAULT_WALLET_SLUG, WALLET_DATA_SOURCE, WALLET_LOCK, WALLET_OPTIONS, } from './tokens.js';
23
+ let WalletService = class WalletService {
24
+ constructor(wallets, transactions, dataSource, options, lockService, events) {
25
+ this.wallets = wallets;
26
+ this.transactions = transactions;
27
+ this.dataSource = dataSource;
28
+ this.lockService = lockService;
29
+ this.events = events;
30
+ this.defaultSlug = options.defaultWalletSlug ?? DEFAULT_WALLET_SLUG;
31
+ this.defaultName = options.defaultWalletName ?? DEFAULT_WALLET_NAME;
32
+ this.lockTtlMs = options.lock?.ttlMs ?? DEFAULT_LOCK_TTL_MS;
33
+ }
34
+ normalizeHolderId(holderId) {
35
+ return String(holderId);
36
+ }
37
+ async createWallet(holderType, holderId, input = {}) {
38
+ const slug = input.slug ?? this.defaultSlug;
39
+ const wallet = this.wallets.create({
40
+ holderType,
41
+ holderId: this.normalizeHolderId(holderId),
42
+ name: input.name ?? this.defaultName,
43
+ slug,
44
+ uuid: randomUUID(),
45
+ description: input.description ?? null,
46
+ meta: input.meta ?? null,
47
+ balance: '0',
48
+ decimalPlaces: input.decimalPlaces ?? 2,
49
+ });
50
+ const saved = await this.wallets.save(wallet);
51
+ this.events.walletCreated({
52
+ walletId: Number(saved.id),
53
+ holderType: saved.holderType,
54
+ holderId: saved.holderId,
55
+ slug: saved.slug,
56
+ uuid: saved.uuid,
57
+ });
58
+ return saved;
59
+ }
60
+ async hasWallet(holderType, holderId, slug) {
61
+ const count = await this.wallets.count({
62
+ where: {
63
+ holderType,
64
+ holderId: this.normalizeHolderId(holderId),
65
+ slug: slug ?? this.defaultSlug,
66
+ },
67
+ });
68
+ return count > 0;
69
+ }
70
+ async getWallet(holderType, holderId, slug) {
71
+ return this.wallets.findOne({
72
+ where: {
73
+ holderType,
74
+ holderId: this.normalizeHolderId(holderId),
75
+ slug: slug ?? this.defaultSlug,
76
+ },
77
+ });
78
+ }
79
+ async getWalletOrFail(holderType, holderId, slug) {
80
+ const wallet = await this.getWallet(holderType, holderId, slug);
81
+ if (!wallet) {
82
+ throw new WalletNotFoundError(`Wallet not found for ${holderType}:${holderId}:${slug ?? this.defaultSlug}`);
83
+ }
84
+ return wallet;
85
+ }
86
+ async getOrCreateWallet(holderType, holderId, input = {}) {
87
+ const slug = input.slug ?? this.defaultSlug;
88
+ const existing = await this.getWallet(holderType, holderId, slug);
89
+ if (existing)
90
+ return existing;
91
+ return this.createWallet(holderType, holderId, { ...input, slug });
92
+ }
93
+ async getWalletById(walletId) {
94
+ const wallet = await this.wallets.findOne({ where: { id: walletId } });
95
+ if (!wallet)
96
+ throw new WalletNotFoundError(`Wallet ${walletId} not found`);
97
+ return wallet;
98
+ }
99
+ balance(wallet) {
100
+ return wallet.balance;
101
+ }
102
+ balanceInt(wallet) {
103
+ return Number(wallet.balance);
104
+ }
105
+ async deposit(wallet, amount, meta = null) {
106
+ const value = this.normalizeAmount(amount);
107
+ if (value <= 0n)
108
+ throw new Error('Deposit amount must be positive');
109
+ return this.lockService.lock(walletLockKey(wallet.id), this.lockTtlMs, async () => {
110
+ return this.dataSource.transaction(async (manager) => {
111
+ const locked = await manager.findOne(WalletEntity, {
112
+ where: { id: wallet.id },
113
+ lock: { mode: 'pessimistic_write' },
114
+ });
115
+ if (!locked)
116
+ throw new WalletNotFoundError();
117
+ const oldBalance = locked.balance;
118
+ const next = (BigInt(locked.balance) + value).toString();
119
+ locked.balance = next;
120
+ await manager.save(locked);
121
+ const tx = manager.create(TransactionEntity, {
122
+ payableType: locked.holderType,
123
+ payableId: locked.holderId,
124
+ walletId: locked.id,
125
+ type: 'deposit',
126
+ amount: value.toString(),
127
+ confirmed: true,
128
+ meta,
129
+ uuid: randomUUID(),
130
+ });
131
+ const savedTx = await manager.save(tx);
132
+ this.events.transactionCreated({
133
+ transactionId: Number(savedTx.id),
134
+ walletId: Number(locked.id),
135
+ type: 'deposit',
136
+ amount: savedTx.amount,
137
+ uuid: savedTx.uuid,
138
+ });
139
+ this.events.balanceUpdated({
140
+ walletId: Number(locked.id),
141
+ holderType: locked.holderType,
142
+ holderId: locked.holderId,
143
+ balance: next,
144
+ oldBalance,
145
+ });
146
+ Object.assign(wallet, locked);
147
+ return savedTx;
148
+ });
149
+ });
150
+ }
151
+ async withdraw(wallet, amount, meta = null) {
152
+ const value = this.normalizeAmount(amount);
153
+ if (value <= 0n)
154
+ throw new Error('Withdraw amount must be positive');
155
+ return this.lockService.lock(walletLockKey(wallet.id), this.lockTtlMs, async () => {
156
+ return this.dataSource.transaction(async (manager) => {
157
+ const locked = await manager.findOne(WalletEntity, {
158
+ where: { id: wallet.id },
159
+ lock: { mode: 'pessimistic_write' },
160
+ });
161
+ if (!locked)
162
+ throw new WalletNotFoundError();
163
+ const current = BigInt(locked.balance);
164
+ if (current < value)
165
+ throw new InsufficientFundsError();
166
+ const oldBalance = locked.balance;
167
+ const next = (current - value).toString();
168
+ locked.balance = next;
169
+ await manager.save(locked);
170
+ const tx = manager.create(TransactionEntity, {
171
+ payableType: locked.holderType,
172
+ payableId: locked.holderId,
173
+ walletId: locked.id,
174
+ type: 'withdraw',
175
+ amount: value.toString(),
176
+ confirmed: true,
177
+ meta,
178
+ uuid: randomUUID(),
179
+ });
180
+ const savedTx = await manager.save(tx);
181
+ this.events.transactionCreated({
182
+ transactionId: Number(savedTx.id),
183
+ walletId: Number(locked.id),
184
+ type: 'withdraw',
185
+ amount: savedTx.amount,
186
+ uuid: savedTx.uuid,
187
+ });
188
+ this.events.balanceUpdated({
189
+ walletId: Number(locked.id),
190
+ holderType: locked.holderType,
191
+ holderId: locked.holderId,
192
+ balance: next,
193
+ oldBalance,
194
+ });
195
+ Object.assign(wallet, locked);
196
+ return savedTx;
197
+ });
198
+ });
199
+ }
200
+ normalizeAmount(amount) {
201
+ if (typeof amount === 'number') {
202
+ if (!Number.isFinite(amount) || !Number.isInteger(amount)) {
203
+ throw new Error('Integer amount required; use float helpers for decimals');
204
+ }
205
+ return BigInt(amount);
206
+ }
207
+ return BigInt(amount);
208
+ }
209
+ floatToInt(amount, decimalPlaces) {
210
+ const factor = 10 ** decimalPlaces;
211
+ return BigInt(Math.round(amount * factor));
212
+ }
213
+ intToFloat(amount, decimalPlaces) {
214
+ const factor = 10 ** decimalPlaces;
215
+ return Number(amount) / factor;
216
+ }
217
+ };
218
+ WalletService = __decorate([
219
+ Injectable(),
220
+ __param(0, InjectRepository(WalletEntity)),
221
+ __param(1, InjectRepository(TransactionEntity)),
222
+ __param(2, Inject(WALLET_DATA_SOURCE)),
223
+ __param(3, Inject(WALLET_OPTIONS)),
224
+ __param(4, Inject(WALLET_LOCK)),
225
+ __metadata("design:paramtypes", [Repository,
226
+ Repository,
227
+ DataSource, Object, Object, WalletEventPublisher])
228
+ ], WalletService);
229
+ export { WalletService };
230
+ //# sourceMappingURL=wallet.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.service.js","sourceRoot":"","sources":["../src/wallet.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Repository } from 'typeorm';
2
+ import { TransactionEntity } from './entities/transaction.entity.js';
3
+ import { WalletEntity } from './entities/wallet.entity.js';
4
+ import { WalletEventPublisher } from './events/wallet-event.publisher.js';
5
+ export declare class WarmupService {
6
+ private readonly wallets;
7
+ private readonly transactions;
8
+ private readonly events;
9
+ constructor(wallets: Repository<WalletEntity>, transactions: Repository<TransactionEntity>, events: WalletEventPublisher);
10
+ warmup(walletId: number): Promise<WalletEntity>;
11
+ warmupAll(): Promise<number>;
12
+ }
13
+ //# sourceMappingURL=warmup.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warmup.service.d.ts","sourceRoot":"","sources":["../src/warmup.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,qBACa,aAAa;IAGtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAHN,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC,EAEjC,YAAY,EAAE,UAAU,CAAC,iBAAiB,CAAC,EAC3C,MAAM,EAAE,oBAAoB;IAGzC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAoC/C,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;CAOnC"}
@@ -0,0 +1,76 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Injectable } from '@nestjs/common';
14
+ import { InjectRepository } from '@nestjs/typeorm';
15
+ import { Repository } from 'typeorm';
16
+ import { TransactionEntity } from './entities/transaction.entity.js';
17
+ import { WalletEntity } from './entities/wallet.entity.js';
18
+ import { WalletNotFoundError } from './errors.js';
19
+ import { WalletEventPublisher } from './events/wallet-event.publisher.js';
20
+ let WarmupService = class WarmupService {
21
+ constructor(wallets, transactions, events) {
22
+ this.wallets = wallets;
23
+ this.transactions = transactions;
24
+ this.events = events;
25
+ }
26
+ async warmup(walletId) {
27
+ const wallet = await this.wallets.findOne({ where: { id: walletId } });
28
+ if (!wallet)
29
+ throw new WalletNotFoundError(`Wallet ${walletId} not found`);
30
+ const rows = await this.transactions
31
+ .createQueryBuilder('t')
32
+ .select('t.type', 'type')
33
+ .addSelect('COALESCE(SUM(t.amount), 0)', 'total')
34
+ .where('t.wallet_id = :walletId', { walletId })
35
+ .andWhere('t.confirmed = :confirmed', { confirmed: true })
36
+ .groupBy('t.type')
37
+ .getRawMany();
38
+ let deposits = 0n;
39
+ let withdraws = 0n;
40
+ for (const row of rows) {
41
+ if (row.type === 'deposit')
42
+ deposits = BigInt(row.total);
43
+ if (row.type === 'withdraw')
44
+ withdraws = BigInt(row.total);
45
+ }
46
+ const oldBalance = wallet.balance;
47
+ const next = (deposits - withdraws).toString();
48
+ wallet.balance = next;
49
+ const saved = await this.wallets.save(wallet);
50
+ this.events.balanceUpdated({
51
+ walletId: Number(saved.id),
52
+ holderType: saved.holderType,
53
+ holderId: saved.holderId,
54
+ balance: next,
55
+ oldBalance,
56
+ });
57
+ return saved;
58
+ }
59
+ async warmupAll() {
60
+ const ids = await this.wallets.find({ select: { id: true } });
61
+ for (const row of ids) {
62
+ await this.warmup(Number(row.id));
63
+ }
64
+ return ids.length;
65
+ }
66
+ };
67
+ WarmupService = __decorate([
68
+ Injectable(),
69
+ __param(0, InjectRepository(WalletEntity)),
70
+ __param(1, InjectRepository(TransactionEntity)),
71
+ __metadata("design:paramtypes", [Repository,
72
+ Repository,
73
+ WalletEventPublisher])
74
+ ], WarmupService);
75
+ export { WarmupService };
76
+ //# sourceMappingURL=warmup.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warmup.service.js","sourceRoot":"","sources":["../src/warmup.service.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@nestjs-dash/wallet",
3
+ "version": "0.1.1",
4
+ "description": "NestJS Bavix-compatible wallet library for NestJS Dash",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "nestjs-dash-wallet": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "type": "module",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "dependencies": {
23
+ "commander": "^15.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "@nestjs-dash/typescript-config": "0.1.0",
27
+ "@nestjs/common": "^12.0.1",
28
+ "@nestjs/core": "^12.0.1",
29
+ "@nestjs/event-emitter": "^12.0.0",
30
+ "@nestjs/typeorm": "^12.0.1",
31
+ "reflect-metadata": "^0.2.2",
32
+ "rxjs": "^7.8.2",
33
+ "typeorm": "^1.1.1",
34
+ "typescript": "6.0.3",
35
+ "vitest": "^5.0.0"
36
+ },
37
+ "peerDependencies": {
38
+ "@nestjs/common": "^12.0.0",
39
+ "@nestjs/core": "^12.0.0",
40
+ "@nestjs/event-emitter": "^3.0.0",
41
+ "@nestjs/typeorm": "^12.0.0",
42
+ "ioredis": ">=5.0.0",
43
+ "memjs": ">=1.0.0",
44
+ "reflect-metadata": "^0.2.2",
45
+ "rxjs": "^7.8.0",
46
+ "typeorm": ">=0.2.41 <0.3.0-0 || ^0.3.20 || ^1.0.0",
47
+ "uuid": ">=9.0.0"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "ioredis": {
51
+ "optional": true
52
+ },
53
+ "memjs": {
54
+ "optional": true
55
+ },
56
+ "uuid": {
57
+ "optional": true
58
+ }
59
+ },
60
+ "scripts": {
61
+ "build": "tsc -p tsconfig.json",
62
+ "check-types": "tsc -p tsconfig.json --noEmit",
63
+ "format": "oxfmt",
64
+ "lint": "oxlint src",
65
+ "test": "vitest run",
66
+ "test:coverage": "vitest run --coverage",
67
+ "dev": "tsc -p tsconfig.json --watch"
68
+ }
69
+ }