@canton-network/core-wallet-store-inmemory 0.11.0 → 0.12.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.
@@ -1 +1 @@
1
- {"version":3,"file":"StoreInternal.d.ts","sourceRoot":"","sources":["../src/StoreInternal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EACH,WAAW,EACX,MAAM,EACN,SAAS,EAEZ,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACH,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,YAAY,EACZ,WAAW,EACX,OAAO,EACV,MAAM,mCAAmC,CAAA;AAI1C,UAAU,WAAW;IACjB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACtB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACtC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAA;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;CAC3B;AAED,KAAK,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAGtC,qBAAa,aAAc,YAAW,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC;IACjE,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,WAAW,CAAQ;IAE3B,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;gBAGhC,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,MAAM;IAUxB,eAAe,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,aAAa;IASrD,MAAM,CAAC,aAAa,IAAI,WAAW;IAQnC,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,aAAa;YAOP,WAAW;IAsEnB,UAAU,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAkB7D,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAK/C,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBjD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxC,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAI1C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW7C,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBrC,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAIvC,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3C,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAM5E"}
1
+ {"version":3,"file":"StoreInternal.d.ts","sourceRoot":"","sources":["../src/StoreInternal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EACH,WAAW,EACX,MAAM,EACN,SAAS,EAGZ,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACH,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,YAAY,EACZ,WAAW,EACX,OAAO,EACV,MAAM,mCAAmC,CAAA;AAM1C,UAAU,WAAW;IACjB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACtB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACtC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAA;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;CAC3B;AAED,KAAK,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAGtC,qBAAa,aAAc,YAAW,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC;IACjE,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,WAAW,CAAQ;IAE3B,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;gBAGhC,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,MAAM;IAUxB,eAAe,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,aAAa;IASrD,MAAM,CAAC,aAAa,IAAI,WAAW;IAQnC,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,aAAa;YAOP,WAAW;IA6EnB,UAAU,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAkB7D,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAK/C,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBjD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxC,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAI1C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW7C,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBrC,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAIvC,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3C,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAM5E"}
package/dist/index.cjs ADDED
@@ -0,0 +1,240 @@
1
+ 'use strict';
2
+
3
+ var coreWalletAuth = require('@canton-network/core-wallet-auth');
4
+ var coreLedgerClient = require('@canton-network/core-ledger-client');
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
9
+ var StoreInternal = class _StoreInternal {
10
+ constructor(config, logger, authContext, userStorage) {
11
+ __publicField(this, "logger");
12
+ __publicField(this, "systemStorage");
13
+ __publicField(this, "userStorage");
14
+ __publicField(this, "authContext");
15
+ this.logger = logger.child({ component: "StoreInternal" });
16
+ this.systemStorage = config;
17
+ this.authContext = authContext;
18
+ this.userStorage = userStorage || /* @__PURE__ */ new Map();
19
+ this.syncWallets();
20
+ }
21
+ withAuthContext(context) {
22
+ return new _StoreInternal(
23
+ this.systemStorage,
24
+ this.logger,
25
+ context,
26
+ this.userStorage
27
+ );
28
+ }
29
+ static createStorage() {
30
+ return {
31
+ wallets: [],
32
+ transactions: /* @__PURE__ */ new Map(),
33
+ session: void 0
34
+ };
35
+ }
36
+ assertConnected() {
37
+ return coreWalletAuth.assertConnected(this.authContext).userId;
38
+ }
39
+ getStorage() {
40
+ const userId = this.assertConnected();
41
+ if (!this.userStorage.has(userId)) {
42
+ this.userStorage.set(userId, _StoreInternal.createStorage());
43
+ }
44
+ return this.userStorage.get(userId);
45
+ }
46
+ updateStorage(storage) {
47
+ const userId = this.assertConnected();
48
+ this.userStorage.set(userId, storage);
49
+ }
50
+ // Wallet methods
51
+ async syncWallets() {
52
+ try {
53
+ const network = await this.getCurrentNetwork();
54
+ const userAccessTokenProvider = {
55
+ getUserAccessToken: async () => this.authContext.accessToken,
56
+ getAdminAccessToken: async () => this.authContext.accessToken
57
+ };
58
+ const ledgerClient = new coreLedgerClient.LedgerClient(
59
+ new URL(network.ledgerApi.baseUrl),
60
+ this.logger,
61
+ false,
62
+ void 0,
63
+ userAccessTokenProvider
64
+ );
65
+ const rights = await ledgerClient.getWithRetry(
66
+ "/v2/users/{user-id}/rights",
67
+ coreLedgerClient.defaultRetryableOptions,
68
+ {
69
+ path: {
70
+ "user-id": this.authContext.userId
71
+ }
72
+ }
73
+ );
74
+ const parties = rights.rights?.filter((right) => "CanActAs" in right.kind).map((right) => {
75
+ if ("CanActAs" in right.kind) {
76
+ return right.kind.CanActAs.value.party;
77
+ }
78
+ throw new Error("Unexpected right kind");
79
+ });
80
+ const existingWallets = await this.getWallets();
81
+ const existingPartyIds = new Set(
82
+ existingWallets.map((w) => w.partyId)
83
+ );
84
+ const participantWallets = parties?.filter(
85
+ (party) => !existingPartyIds.has(party)
86
+ // todo: filter on idp id
87
+ ).map((party) => {
88
+ const [hint, namespace] = party.split("::");
89
+ return {
90
+ primary: false,
91
+ partyId: party,
92
+ hint,
93
+ publicKey: namespace,
94
+ namespace,
95
+ chainId: network.chainId,
96
+ signingProviderId: "participant"
97
+ // todo: determine based on partyDetails.isLocal
98
+ };
99
+ }) || [];
100
+ const storage = this.getStorage();
101
+ const wallets = [...storage.wallets, ...participantWallets];
102
+ const hasPrimary = wallets.some((w) => w.primary);
103
+ if (!hasPrimary && wallets.length > 0) {
104
+ wallets[0].primary = true;
105
+ }
106
+ this.logger.debug(wallets, "Wallets synchronized");
107
+ storage.wallets = wallets;
108
+ this.updateStorage(storage);
109
+ } catch {
110
+ return;
111
+ }
112
+ }
113
+ async getWallets(filter = {}) {
114
+ const { chainIds, signingProviderIds } = filter;
115
+ const chainIdSet = chainIds ? new Set(chainIds) : null;
116
+ const signingProviderIdSet = signingProviderIds ? new Set(signingProviderIds) : null;
117
+ return this.getStorage().wallets.filter((wallet) => {
118
+ const matchedChainIds = chainIdSet ? chainIdSet.has(wallet.chainId) : true;
119
+ const matchedStorageProviderIdS = signingProviderIdSet ? signingProviderIdSet.has(wallet.signingProviderId) : true;
120
+ return matchedChainIds && matchedStorageProviderIdS;
121
+ });
122
+ }
123
+ async getPrimaryWallet() {
124
+ const wallets = await this.getWallets();
125
+ return wallets.find((w) => w.primary === true);
126
+ }
127
+ async setPrimaryWallet(partyId) {
128
+ const storage = this.getStorage();
129
+ if (!storage.wallets.some((w) => w.partyId === partyId)) {
130
+ throw new Error(`Wallet with partyId "${partyId}" not found`);
131
+ }
132
+ const wallets = storage.wallets.map((w) => {
133
+ if (w.partyId === partyId) {
134
+ w.primary = true;
135
+ } else {
136
+ w.primary = false;
137
+ }
138
+ return w;
139
+ });
140
+ storage.wallets = wallets;
141
+ this.updateStorage(storage);
142
+ }
143
+ async addWallet(wallet) {
144
+ const storage = this.getStorage();
145
+ if (storage.wallets.some((w) => w.partyId === wallet.partyId)) {
146
+ throw new Error(
147
+ `Wallet with partyId "${wallet.partyId}" already exists`
148
+ );
149
+ }
150
+ const wallets = await this.getWallets();
151
+ if (wallets.length === 0) {
152
+ wallet.primary = true;
153
+ }
154
+ if (wallet.primary) {
155
+ storage.wallets.map((w) => w.primary = false);
156
+ }
157
+ wallets.push(wallet);
158
+ storage.wallets = wallets;
159
+ this.updateStorage(storage);
160
+ }
161
+ // Session methods
162
+ async getSession() {
163
+ return this.getStorage().session;
164
+ }
165
+ async setSession(session) {
166
+ const storage = this.getStorage();
167
+ storage.session = session;
168
+ this.updateStorage(storage);
169
+ }
170
+ async removeSession() {
171
+ const storage = this.getStorage();
172
+ storage.session = void 0;
173
+ this.updateStorage(storage);
174
+ }
175
+ // Network methods
176
+ async getNetwork(chainId) {
177
+ this.assertConnected();
178
+ const networks = await this.listNetworks();
179
+ if (!networks) throw new Error("No networks available");
180
+ const network = networks.find((n) => n.chainId === chainId);
181
+ if (!network) throw new Error(`Network "${chainId}" not found`);
182
+ return network;
183
+ }
184
+ async getCurrentNetwork() {
185
+ const session = this.getStorage().session;
186
+ if (!session) {
187
+ throw new Error("No session found");
188
+ }
189
+ const chainId = session.network;
190
+ if (!chainId) {
191
+ throw new Error("No current network set in session");
192
+ }
193
+ const networks = await this.listNetworks();
194
+ const network = networks.find((n) => n.chainId === chainId);
195
+ if (!network) {
196
+ throw new Error(`Network "${chainId}" not found`);
197
+ }
198
+ return network;
199
+ }
200
+ async listNetworks() {
201
+ return this.systemStorage.networks;
202
+ }
203
+ async updateNetwork(network) {
204
+ this.assertConnected();
205
+ this.removeNetwork(network.chainId);
206
+ this.systemStorage.networks.push(network);
207
+ }
208
+ async addNetwork(network) {
209
+ const networkAlreadyExists = this.systemStorage.networks.find(
210
+ (n) => n.chainId === network.chainId
211
+ );
212
+ if (networkAlreadyExists) {
213
+ throw new Error(`Network ${network.chainId} already exists`);
214
+ } else {
215
+ this.systemStorage.networks.push(network);
216
+ }
217
+ }
218
+ async removeNetwork(chainId) {
219
+ this.assertConnected();
220
+ this.systemStorage.networks = this.systemStorage.networks.filter(
221
+ (n) => n.chainId !== chainId
222
+ );
223
+ }
224
+ // Transaction methods
225
+ async setTransaction(transaction) {
226
+ this.assertConnected();
227
+ const storage = this.getStorage();
228
+ storage.transactions.set(transaction.commandId, transaction);
229
+ this.updateStorage(storage);
230
+ }
231
+ async getTransaction(commandId) {
232
+ this.assertConnected();
233
+ const storage = this.getStorage();
234
+ return storage.transactions.get(commandId);
235
+ }
236
+ };
237
+
238
+ exports.StoreInternal = StoreInternal;
239
+ //# sourceMappingURL=index.cjs.map
240
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/StoreInternal.ts"],"names":["assertConnected","LedgerClient","defaultRetryableOptions"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from 'pino'\nimport {\n AuthContext,\n UserId,\n AuthAware,\n assertConnected,\n AccessTokenProvider,\n} from '@canton-network/core-wallet-auth'\nimport {\n Store,\n Wallet,\n PartyId,\n Session,\n WalletFilter,\n Transaction,\n Network,\n} from '@canton-network/core-wallet-store'\nimport {\n LedgerClient,\n defaultRetryableOptions,\n} from '@canton-network/core-ledger-client'\n\ninterface UserStorage {\n wallets: Array<Wallet>\n transactions: Map<string, Transaction>\n session: Session | undefined\n}\n\nexport interface StoreInternalConfig {\n networks: Array<Network>\n}\n\ntype Memory = Map<UserId, UserStorage>\n\n// TODO: remove AuthAware and instead provide wrapper in clients\nexport class StoreInternal implements Store, AuthAware<StoreInternal> {\n private logger: Logger\n private systemStorage: StoreInternalConfig\n private userStorage: Memory\n\n authContext: AuthContext | undefined\n\n constructor(\n config: StoreInternalConfig,\n logger: Logger,\n authContext?: AuthContext,\n userStorage?: Memory\n ) {\n this.logger = logger.child({ component: 'StoreInternal' })\n this.systemStorage = config\n this.authContext = authContext\n this.userStorage = userStorage || new Map()\n\n this.syncWallets()\n }\n\n withAuthContext(context?: AuthContext): StoreInternal {\n return new StoreInternal(\n this.systemStorage,\n this.logger,\n context,\n this.userStorage\n )\n }\n\n static createStorage(): UserStorage {\n return {\n wallets: [],\n transactions: new Map<string, Transaction>(),\n session: undefined,\n }\n }\n\n private assertConnected(): UserId {\n return assertConnected(this.authContext).userId\n }\n\n private getStorage(): UserStorage {\n const userId = this.assertConnected()\n if (!this.userStorage.has(userId)) {\n this.userStorage.set(userId, StoreInternal.createStorage())\n }\n return this.userStorage.get(userId)!\n }\n\n private updateStorage(storage: UserStorage): void {\n const userId = this.assertConnected()\n this.userStorage.set(userId, storage)\n }\n\n // Wallet methods\n\n private async syncWallets(): Promise<void> {\n try {\n const network = await this.getCurrentNetwork()\n\n // Get existing parties from participant\n const userAccessTokenProvider: AccessTokenProvider = {\n getUserAccessToken: async () => this.authContext!.accessToken,\n getAdminAccessToken: async () => this.authContext!.accessToken,\n }\n\n const ledgerClient = new LedgerClient(\n new URL(network.ledgerApi.baseUrl),\n this.logger,\n false,\n undefined,\n userAccessTokenProvider\n )\n const rights = await ledgerClient.getWithRetry(\n '/v2/users/{user-id}/rights',\n defaultRetryableOptions,\n {\n path: {\n 'user-id': this.authContext!.userId,\n },\n }\n )\n const parties = rights.rights\n ?.filter((right) => 'CanActAs' in right.kind)\n .map((right) => {\n if ('CanActAs' in right.kind) {\n return right.kind.CanActAs.value.party\n }\n throw new Error('Unexpected right kind')\n })\n\n // Merge Wallets\n const existingWallets = await this.getWallets()\n const existingPartyIds = new Set(\n existingWallets.map((w) => w.partyId)\n )\n const participantWallets: Array<Wallet> =\n parties\n ?.filter(\n (party) => !existingPartyIds.has(party)\n // todo: filter on idp id\n )\n .map((party) => {\n const [hint, namespace] = party.split('::')\n return {\n primary: false,\n partyId: party,\n hint: hint,\n publicKey: namespace,\n namespace: namespace,\n chainId: network.chainId,\n signingProviderId: 'participant', // todo: determine based on partyDetails.isLocal\n }\n }) || []\n const storage = this.getStorage()\n const wallets = [...storage.wallets, ...participantWallets]\n\n // Set primary wallet if none exists\n const hasPrimary = wallets.some((w) => w.primary)\n if (!hasPrimary && wallets.length > 0) {\n wallets[0].primary = true\n }\n\n this.logger.debug(wallets, 'Wallets synchronized')\n\n // Update storage with new wallets\n storage.wallets = wallets\n this.updateStorage(storage)\n } catch {\n return\n }\n }\n\n async getWallets(filter: WalletFilter = {}): Promise<Array<Wallet>> {\n const { chainIds, signingProviderIds } = filter\n const chainIdSet = chainIds ? new Set(chainIds) : null\n const signingProviderIdSet = signingProviderIds\n ? new Set(signingProviderIds)\n : null\n\n return this.getStorage().wallets.filter((wallet) => {\n const matchedChainIds = chainIdSet\n ? chainIdSet.has(wallet.chainId)\n : true\n const matchedStorageProviderIdS = signingProviderIdSet\n ? signingProviderIdSet.has(wallet.signingProviderId)\n : true\n return matchedChainIds && matchedStorageProviderIdS\n })\n }\n\n async getPrimaryWallet(): Promise<Wallet | undefined> {\n const wallets = await this.getWallets()\n return wallets.find((w) => w.primary === true)\n }\n\n async setPrimaryWallet(partyId: PartyId): Promise<void> {\n const storage = this.getStorage()\n if (!storage.wallets.some((w) => w.partyId === partyId)) {\n throw new Error(`Wallet with partyId \"${partyId}\" not found`)\n }\n const wallets = storage.wallets.map((w) => {\n if (w.partyId === partyId) {\n w.primary = true\n } else {\n w.primary = false\n }\n return w\n })\n storage.wallets = wallets\n this.updateStorage(storage)\n }\n\n async addWallet(wallet: Wallet): Promise<void> {\n const storage = this.getStorage()\n if (storage.wallets.some((w) => w.partyId === wallet.partyId)) {\n throw new Error(\n `Wallet with partyId \"${wallet.partyId}\" already exists`\n )\n }\n const wallets = await this.getWallets()\n\n if (wallets.length === 0) {\n // If this is the first wallet, set it as primary automatically\n wallet.primary = true\n }\n\n if (wallet.primary) {\n // If the new wallet is primary, set all others to non-primary\n storage.wallets.map((w) => (w.primary = false))\n }\n wallets.push(wallet)\n storage.wallets = wallets\n this.updateStorage(storage)\n }\n\n // Session methods\n async getSession(): Promise<Session | undefined> {\n return this.getStorage().session\n }\n\n async setSession(session: Session): Promise<void> {\n const storage = this.getStorage()\n storage.session = session\n this.updateStorage(storage)\n }\n\n async removeSession(): Promise<void> {\n const storage = this.getStorage()\n storage.session = undefined\n this.updateStorage(storage)\n }\n\n // Network methods\n async getNetwork(chainId: string): Promise<Network> {\n this.assertConnected()\n\n const networks = await this.listNetworks()\n if (!networks) throw new Error('No networks available')\n\n const network = networks.find((n) => n.chainId === chainId)\n if (!network) throw new Error(`Network \"${chainId}\" not found`)\n return network\n }\n\n async getCurrentNetwork(): Promise<Network> {\n const session = this.getStorage().session\n if (!session) {\n throw new Error('No session found')\n }\n const chainId = session.network\n if (!chainId) {\n throw new Error('No current network set in session')\n }\n\n const networks = await this.listNetworks()\n const network = networks.find((n) => n.chainId === chainId)\n if (!network) {\n throw new Error(`Network \"${chainId}\" not found`)\n }\n return network\n }\n\n async listNetworks(): Promise<Array<Network>> {\n return this.systemStorage.networks\n }\n\n async updateNetwork(network: Network): Promise<void> {\n this.assertConnected()\n this.removeNetwork(network.chainId) // Ensure no duplicates\n this.systemStorage.networks.push(network)\n }\n\n async addNetwork(network: Network): Promise<void> {\n const networkAlreadyExists = this.systemStorage.networks.find(\n (n) => n.chainId === network.chainId\n )\n if (networkAlreadyExists) {\n throw new Error(`Network ${network.chainId} already exists`)\n } else {\n this.systemStorage.networks.push(network)\n }\n }\n\n async removeNetwork(chainId: string): Promise<void> {\n this.assertConnected()\n this.systemStorage.networks = this.systemStorage.networks.filter(\n (n) => n.chainId !== chainId\n )\n }\n\n // Transaction methods\n async setTransaction(transaction: Transaction): Promise<void> {\n this.assertConnected()\n const storage = this.getStorage()\n\n storage.transactions.set(transaction.commandId, transaction)\n this.updateStorage(storage)\n }\n\n async getTransaction(commandId: string): Promise<Transaction | undefined> {\n this.assertConnected()\n const storage = this.getStorage()\n\n return storage.transactions.get(commandId)\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -1,3 +1,238 @@
1
- // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
- // SPDX-License-Identifier: Apache-2.0
3
- export * from './StoreInternal.js';
1
+ import { assertConnected } from '@canton-network/core-wallet-auth';
2
+ import { LedgerClient, defaultRetryableOptions } from '@canton-network/core-ledger-client';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+ var StoreInternal = class _StoreInternal {
8
+ constructor(config, logger, authContext, userStorage) {
9
+ __publicField(this, "logger");
10
+ __publicField(this, "systemStorage");
11
+ __publicField(this, "userStorage");
12
+ __publicField(this, "authContext");
13
+ this.logger = logger.child({ component: "StoreInternal" });
14
+ this.systemStorage = config;
15
+ this.authContext = authContext;
16
+ this.userStorage = userStorage || /* @__PURE__ */ new Map();
17
+ this.syncWallets();
18
+ }
19
+ withAuthContext(context) {
20
+ return new _StoreInternal(
21
+ this.systemStorage,
22
+ this.logger,
23
+ context,
24
+ this.userStorage
25
+ );
26
+ }
27
+ static createStorage() {
28
+ return {
29
+ wallets: [],
30
+ transactions: /* @__PURE__ */ new Map(),
31
+ session: void 0
32
+ };
33
+ }
34
+ assertConnected() {
35
+ return assertConnected(this.authContext).userId;
36
+ }
37
+ getStorage() {
38
+ const userId = this.assertConnected();
39
+ if (!this.userStorage.has(userId)) {
40
+ this.userStorage.set(userId, _StoreInternal.createStorage());
41
+ }
42
+ return this.userStorage.get(userId);
43
+ }
44
+ updateStorage(storage) {
45
+ const userId = this.assertConnected();
46
+ this.userStorage.set(userId, storage);
47
+ }
48
+ // Wallet methods
49
+ async syncWallets() {
50
+ try {
51
+ const network = await this.getCurrentNetwork();
52
+ const userAccessTokenProvider = {
53
+ getUserAccessToken: async () => this.authContext.accessToken,
54
+ getAdminAccessToken: async () => this.authContext.accessToken
55
+ };
56
+ const ledgerClient = new LedgerClient(
57
+ new URL(network.ledgerApi.baseUrl),
58
+ this.logger,
59
+ false,
60
+ void 0,
61
+ userAccessTokenProvider
62
+ );
63
+ const rights = await ledgerClient.getWithRetry(
64
+ "/v2/users/{user-id}/rights",
65
+ defaultRetryableOptions,
66
+ {
67
+ path: {
68
+ "user-id": this.authContext.userId
69
+ }
70
+ }
71
+ );
72
+ const parties = rights.rights?.filter((right) => "CanActAs" in right.kind).map((right) => {
73
+ if ("CanActAs" in right.kind) {
74
+ return right.kind.CanActAs.value.party;
75
+ }
76
+ throw new Error("Unexpected right kind");
77
+ });
78
+ const existingWallets = await this.getWallets();
79
+ const existingPartyIds = new Set(
80
+ existingWallets.map((w) => w.partyId)
81
+ );
82
+ const participantWallets = parties?.filter(
83
+ (party) => !existingPartyIds.has(party)
84
+ // todo: filter on idp id
85
+ ).map((party) => {
86
+ const [hint, namespace] = party.split("::");
87
+ return {
88
+ primary: false,
89
+ partyId: party,
90
+ hint,
91
+ publicKey: namespace,
92
+ namespace,
93
+ chainId: network.chainId,
94
+ signingProviderId: "participant"
95
+ // todo: determine based on partyDetails.isLocal
96
+ };
97
+ }) || [];
98
+ const storage = this.getStorage();
99
+ const wallets = [...storage.wallets, ...participantWallets];
100
+ const hasPrimary = wallets.some((w) => w.primary);
101
+ if (!hasPrimary && wallets.length > 0) {
102
+ wallets[0].primary = true;
103
+ }
104
+ this.logger.debug(wallets, "Wallets synchronized");
105
+ storage.wallets = wallets;
106
+ this.updateStorage(storage);
107
+ } catch {
108
+ return;
109
+ }
110
+ }
111
+ async getWallets(filter = {}) {
112
+ const { chainIds, signingProviderIds } = filter;
113
+ const chainIdSet = chainIds ? new Set(chainIds) : null;
114
+ const signingProviderIdSet = signingProviderIds ? new Set(signingProviderIds) : null;
115
+ return this.getStorage().wallets.filter((wallet) => {
116
+ const matchedChainIds = chainIdSet ? chainIdSet.has(wallet.chainId) : true;
117
+ const matchedStorageProviderIdS = signingProviderIdSet ? signingProviderIdSet.has(wallet.signingProviderId) : true;
118
+ return matchedChainIds && matchedStorageProviderIdS;
119
+ });
120
+ }
121
+ async getPrimaryWallet() {
122
+ const wallets = await this.getWallets();
123
+ return wallets.find((w) => w.primary === true);
124
+ }
125
+ async setPrimaryWallet(partyId) {
126
+ const storage = this.getStorage();
127
+ if (!storage.wallets.some((w) => w.partyId === partyId)) {
128
+ throw new Error(`Wallet with partyId "${partyId}" not found`);
129
+ }
130
+ const wallets = storage.wallets.map((w) => {
131
+ if (w.partyId === partyId) {
132
+ w.primary = true;
133
+ } else {
134
+ w.primary = false;
135
+ }
136
+ return w;
137
+ });
138
+ storage.wallets = wallets;
139
+ this.updateStorage(storage);
140
+ }
141
+ async addWallet(wallet) {
142
+ const storage = this.getStorage();
143
+ if (storage.wallets.some((w) => w.partyId === wallet.partyId)) {
144
+ throw new Error(
145
+ `Wallet with partyId "${wallet.partyId}" already exists`
146
+ );
147
+ }
148
+ const wallets = await this.getWallets();
149
+ if (wallets.length === 0) {
150
+ wallet.primary = true;
151
+ }
152
+ if (wallet.primary) {
153
+ storage.wallets.map((w) => w.primary = false);
154
+ }
155
+ wallets.push(wallet);
156
+ storage.wallets = wallets;
157
+ this.updateStorage(storage);
158
+ }
159
+ // Session methods
160
+ async getSession() {
161
+ return this.getStorage().session;
162
+ }
163
+ async setSession(session) {
164
+ const storage = this.getStorage();
165
+ storage.session = session;
166
+ this.updateStorage(storage);
167
+ }
168
+ async removeSession() {
169
+ const storage = this.getStorage();
170
+ storage.session = void 0;
171
+ this.updateStorage(storage);
172
+ }
173
+ // Network methods
174
+ async getNetwork(chainId) {
175
+ this.assertConnected();
176
+ const networks = await this.listNetworks();
177
+ if (!networks) throw new Error("No networks available");
178
+ const network = networks.find((n) => n.chainId === chainId);
179
+ if (!network) throw new Error(`Network "${chainId}" not found`);
180
+ return network;
181
+ }
182
+ async getCurrentNetwork() {
183
+ const session = this.getStorage().session;
184
+ if (!session) {
185
+ throw new Error("No session found");
186
+ }
187
+ const chainId = session.network;
188
+ if (!chainId) {
189
+ throw new Error("No current network set in session");
190
+ }
191
+ const networks = await this.listNetworks();
192
+ const network = networks.find((n) => n.chainId === chainId);
193
+ if (!network) {
194
+ throw new Error(`Network "${chainId}" not found`);
195
+ }
196
+ return network;
197
+ }
198
+ async listNetworks() {
199
+ return this.systemStorage.networks;
200
+ }
201
+ async updateNetwork(network) {
202
+ this.assertConnected();
203
+ this.removeNetwork(network.chainId);
204
+ this.systemStorage.networks.push(network);
205
+ }
206
+ async addNetwork(network) {
207
+ const networkAlreadyExists = this.systemStorage.networks.find(
208
+ (n) => n.chainId === network.chainId
209
+ );
210
+ if (networkAlreadyExists) {
211
+ throw new Error(`Network ${network.chainId} already exists`);
212
+ } else {
213
+ this.systemStorage.networks.push(network);
214
+ }
215
+ }
216
+ async removeNetwork(chainId) {
217
+ this.assertConnected();
218
+ this.systemStorage.networks = this.systemStorage.networks.filter(
219
+ (n) => n.chainId !== chainId
220
+ );
221
+ }
222
+ // Transaction methods
223
+ async setTransaction(transaction) {
224
+ this.assertConnected();
225
+ const storage = this.getStorage();
226
+ storage.transactions.set(transaction.commandId, transaction);
227
+ this.updateStorage(storage);
228
+ }
229
+ async getTransaction(commandId) {
230
+ this.assertConnected();
231
+ const storage = this.getStorage();
232
+ return storage.transactions.get(commandId);
233
+ }
234
+ };
235
+
236
+ export { StoreInternal };
237
+ //# sourceMappingURL=index.js.map
238
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/StoreInternal.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from 'pino'\nimport {\n AuthContext,\n UserId,\n AuthAware,\n assertConnected,\n AccessTokenProvider,\n} from '@canton-network/core-wallet-auth'\nimport {\n Store,\n Wallet,\n PartyId,\n Session,\n WalletFilter,\n Transaction,\n Network,\n} from '@canton-network/core-wallet-store'\nimport {\n LedgerClient,\n defaultRetryableOptions,\n} from '@canton-network/core-ledger-client'\n\ninterface UserStorage {\n wallets: Array<Wallet>\n transactions: Map<string, Transaction>\n session: Session | undefined\n}\n\nexport interface StoreInternalConfig {\n networks: Array<Network>\n}\n\ntype Memory = Map<UserId, UserStorage>\n\n// TODO: remove AuthAware and instead provide wrapper in clients\nexport class StoreInternal implements Store, AuthAware<StoreInternal> {\n private logger: Logger\n private systemStorage: StoreInternalConfig\n private userStorage: Memory\n\n authContext: AuthContext | undefined\n\n constructor(\n config: StoreInternalConfig,\n logger: Logger,\n authContext?: AuthContext,\n userStorage?: Memory\n ) {\n this.logger = logger.child({ component: 'StoreInternal' })\n this.systemStorage = config\n this.authContext = authContext\n this.userStorage = userStorage || new Map()\n\n this.syncWallets()\n }\n\n withAuthContext(context?: AuthContext): StoreInternal {\n return new StoreInternal(\n this.systemStorage,\n this.logger,\n context,\n this.userStorage\n )\n }\n\n static createStorage(): UserStorage {\n return {\n wallets: [],\n transactions: new Map<string, Transaction>(),\n session: undefined,\n }\n }\n\n private assertConnected(): UserId {\n return assertConnected(this.authContext).userId\n }\n\n private getStorage(): UserStorage {\n const userId = this.assertConnected()\n if (!this.userStorage.has(userId)) {\n this.userStorage.set(userId, StoreInternal.createStorage())\n }\n return this.userStorage.get(userId)!\n }\n\n private updateStorage(storage: UserStorage): void {\n const userId = this.assertConnected()\n this.userStorage.set(userId, storage)\n }\n\n // Wallet methods\n\n private async syncWallets(): Promise<void> {\n try {\n const network = await this.getCurrentNetwork()\n\n // Get existing parties from participant\n const userAccessTokenProvider: AccessTokenProvider = {\n getUserAccessToken: async () => this.authContext!.accessToken,\n getAdminAccessToken: async () => this.authContext!.accessToken,\n }\n\n const ledgerClient = new LedgerClient(\n new URL(network.ledgerApi.baseUrl),\n this.logger,\n false,\n undefined,\n userAccessTokenProvider\n )\n const rights = await ledgerClient.getWithRetry(\n '/v2/users/{user-id}/rights',\n defaultRetryableOptions,\n {\n path: {\n 'user-id': this.authContext!.userId,\n },\n }\n )\n const parties = rights.rights\n ?.filter((right) => 'CanActAs' in right.kind)\n .map((right) => {\n if ('CanActAs' in right.kind) {\n return right.kind.CanActAs.value.party\n }\n throw new Error('Unexpected right kind')\n })\n\n // Merge Wallets\n const existingWallets = await this.getWallets()\n const existingPartyIds = new Set(\n existingWallets.map((w) => w.partyId)\n )\n const participantWallets: Array<Wallet> =\n parties\n ?.filter(\n (party) => !existingPartyIds.has(party)\n // todo: filter on idp id\n )\n .map((party) => {\n const [hint, namespace] = party.split('::')\n return {\n primary: false,\n partyId: party,\n hint: hint,\n publicKey: namespace,\n namespace: namespace,\n chainId: network.chainId,\n signingProviderId: 'participant', // todo: determine based on partyDetails.isLocal\n }\n }) || []\n const storage = this.getStorage()\n const wallets = [...storage.wallets, ...participantWallets]\n\n // Set primary wallet if none exists\n const hasPrimary = wallets.some((w) => w.primary)\n if (!hasPrimary && wallets.length > 0) {\n wallets[0].primary = true\n }\n\n this.logger.debug(wallets, 'Wallets synchronized')\n\n // Update storage with new wallets\n storage.wallets = wallets\n this.updateStorage(storage)\n } catch {\n return\n }\n }\n\n async getWallets(filter: WalletFilter = {}): Promise<Array<Wallet>> {\n const { chainIds, signingProviderIds } = filter\n const chainIdSet = chainIds ? new Set(chainIds) : null\n const signingProviderIdSet = signingProviderIds\n ? new Set(signingProviderIds)\n : null\n\n return this.getStorage().wallets.filter((wallet) => {\n const matchedChainIds = chainIdSet\n ? chainIdSet.has(wallet.chainId)\n : true\n const matchedStorageProviderIdS = signingProviderIdSet\n ? signingProviderIdSet.has(wallet.signingProviderId)\n : true\n return matchedChainIds && matchedStorageProviderIdS\n })\n }\n\n async getPrimaryWallet(): Promise<Wallet | undefined> {\n const wallets = await this.getWallets()\n return wallets.find((w) => w.primary === true)\n }\n\n async setPrimaryWallet(partyId: PartyId): Promise<void> {\n const storage = this.getStorage()\n if (!storage.wallets.some((w) => w.partyId === partyId)) {\n throw new Error(`Wallet with partyId \"${partyId}\" not found`)\n }\n const wallets = storage.wallets.map((w) => {\n if (w.partyId === partyId) {\n w.primary = true\n } else {\n w.primary = false\n }\n return w\n })\n storage.wallets = wallets\n this.updateStorage(storage)\n }\n\n async addWallet(wallet: Wallet): Promise<void> {\n const storage = this.getStorage()\n if (storage.wallets.some((w) => w.partyId === wallet.partyId)) {\n throw new Error(\n `Wallet with partyId \"${wallet.partyId}\" already exists`\n )\n }\n const wallets = await this.getWallets()\n\n if (wallets.length === 0) {\n // If this is the first wallet, set it as primary automatically\n wallet.primary = true\n }\n\n if (wallet.primary) {\n // If the new wallet is primary, set all others to non-primary\n storage.wallets.map((w) => (w.primary = false))\n }\n wallets.push(wallet)\n storage.wallets = wallets\n this.updateStorage(storage)\n }\n\n // Session methods\n async getSession(): Promise<Session | undefined> {\n return this.getStorage().session\n }\n\n async setSession(session: Session): Promise<void> {\n const storage = this.getStorage()\n storage.session = session\n this.updateStorage(storage)\n }\n\n async removeSession(): Promise<void> {\n const storage = this.getStorage()\n storage.session = undefined\n this.updateStorage(storage)\n }\n\n // Network methods\n async getNetwork(chainId: string): Promise<Network> {\n this.assertConnected()\n\n const networks = await this.listNetworks()\n if (!networks) throw new Error('No networks available')\n\n const network = networks.find((n) => n.chainId === chainId)\n if (!network) throw new Error(`Network \"${chainId}\" not found`)\n return network\n }\n\n async getCurrentNetwork(): Promise<Network> {\n const session = this.getStorage().session\n if (!session) {\n throw new Error('No session found')\n }\n const chainId = session.network\n if (!chainId) {\n throw new Error('No current network set in session')\n }\n\n const networks = await this.listNetworks()\n const network = networks.find((n) => n.chainId === chainId)\n if (!network) {\n throw new Error(`Network \"${chainId}\" not found`)\n }\n return network\n }\n\n async listNetworks(): Promise<Array<Network>> {\n return this.systemStorage.networks\n }\n\n async updateNetwork(network: Network): Promise<void> {\n this.assertConnected()\n this.removeNetwork(network.chainId) // Ensure no duplicates\n this.systemStorage.networks.push(network)\n }\n\n async addNetwork(network: Network): Promise<void> {\n const networkAlreadyExists = this.systemStorage.networks.find(\n (n) => n.chainId === network.chainId\n )\n if (networkAlreadyExists) {\n throw new Error(`Network ${network.chainId} already exists`)\n } else {\n this.systemStorage.networks.push(network)\n }\n }\n\n async removeNetwork(chainId: string): Promise<void> {\n this.assertConnected()\n this.systemStorage.networks = this.systemStorage.networks.filter(\n (n) => n.chainId !== chainId\n )\n }\n\n // Transaction methods\n async setTransaction(transaction: Transaction): Promise<void> {\n this.assertConnected()\n const storage = this.getStorage()\n\n storage.transactions.set(transaction.commandId, transaction)\n this.updateStorage(storage)\n }\n\n async getTransaction(commandId: string): Promise<Transaction | undefined> {\n this.assertConnected()\n const storage = this.getStorage()\n\n return storage.transactions.get(commandId)\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canton-network/core-wallet-store-inmemory",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "In-memory implementation of the Store API",
6
6
  "repository": "github:hyperledger-labs/splice-wallet-kernel",
@@ -10,17 +10,18 @@
10
10
  "main": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",
12
12
  "scripts": {
13
- "build": "tsc -b",
14
- "dev": "tsc -b --watch",
13
+ "build": "tsup && tsc -p tsconfig.types.json",
14
+ "dev": "tsup --watch --onSuccess \"tsc -p tsconfig.types.json\"",
15
15
  "flatpack": "yarn pack --out \"$FLATPACK_OUTDIR\"",
16
16
  "clean": "tsc -b --clean; rm -rf dist",
17
17
  "test": "yarn node --experimental-vm-modules $(yarn bin jest)"
18
18
  },
19
19
  "dependencies": {
20
- "@canton-network/core-ledger-client": "^0.15.0",
21
- "@canton-network/core-rpc-errors": "^0.6.0",
22
- "@canton-network/core-wallet-auth": "^0.10.0",
23
- "@canton-network/core-wallet-store": "^0.9.0",
20
+ "@canton-network/core-ledger-client": "^0.16.0",
21
+ "@canton-network/core-rpc-errors": "^0.7.0",
22
+ "@canton-network/core-types": "^0.10.0",
23
+ "@canton-network/core-wallet-auth": "^0.11.0",
24
+ "@canton-network/core-wallet-store": "^0.10.0",
24
25
  "pino": "^10.0.0",
25
26
  "zod": "^3.25.64"
26
27
  },
@@ -33,6 +34,7 @@
33
34
  "pino-test": "^1.1.0",
34
35
  "ts-jest": "^29.4.0",
35
36
  "ts-jest-resolver": "^2.0.1",
37
+ "tsup": "^8.5.0",
36
38
  "typescript": "^5.8.3"
37
39
  },
38
40
  "files": [
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=Store.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Store.test.d.ts","sourceRoot":"","sources":["../src/Store.test.ts"],"names":[],"mappings":""}
@@ -1,159 +0,0 @@
1
- // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { beforeEach, describe, expect, test } from '@jest/globals';
4
- import { StoreInternal } from './StoreInternal';
5
- import { pino } from 'pino';
6
- import { sink } from 'pino-test';
7
- const authContextMock = {
8
- userId: 'test-user-id',
9
- accessToken: 'test-access-token',
10
- };
11
- const storeConfig = {
12
- networks: [],
13
- };
14
- const implementations = [
15
- ['StoreInternal', StoreInternal],
16
- ];
17
- implementations.forEach(([name, StoreImpl]) => {
18
- describe(name, () => {
19
- let store;
20
- beforeEach(() => {
21
- store = new StoreImpl(storeConfig, pino(sink()), authContextMock);
22
- });
23
- test('should add and retrieve wallets', async () => {
24
- const wallet = {
25
- primary: false,
26
- partyId: 'party1',
27
- hint: 'hint',
28
- signingProviderId: 'internal',
29
- publicKey: 'publicKey',
30
- namespace: 'namespace',
31
- chainId: 'network1',
32
- };
33
- await store.addWallet(wallet);
34
- const wallets = await store.getWallets();
35
- expect(wallets).toHaveLength(1);
36
- });
37
- test('should filter wallets', async () => {
38
- const wallet1 = {
39
- primary: false,
40
- partyId: 'party1',
41
- hint: 'hint1',
42
- signingProviderId: 'internal1',
43
- publicKey: 'publicKey',
44
- namespace: 'namespace',
45
- chainId: 'network1',
46
- };
47
- const wallet2 = {
48
- primary: false,
49
- partyId: 'party2',
50
- hint: 'hint2',
51
- signingProviderId: 'internal2',
52
- publicKey: 'publicKey',
53
- namespace: 'namespace',
54
- chainId: 'network1',
55
- };
56
- const wallet3 = {
57
- primary: false,
58
- partyId: 'party3',
59
- hint: 'hint3',
60
- signingProviderId: 'internal2',
61
- publicKey: 'publicKey',
62
- namespace: 'namespace',
63
- chainId: 'network2',
64
- };
65
- await store.addWallet(wallet1);
66
- await store.addWallet(wallet2);
67
- await store.addWallet(wallet3);
68
- const getAllWallets = await store.getWallets();
69
- const getWalletsByChainId = await store.getWallets({
70
- chainIds: ['network1'],
71
- });
72
- const getWalletsBySigningProviderId = await store.getWallets({
73
- signingProviderIds: ['internal2'],
74
- });
75
- const getWalletsByChainIdAndSigningProviderId = await store.getWallets({
76
- chainIds: ['network1'],
77
- signingProviderIds: ['internal2'],
78
- });
79
- expect(getAllWallets).toHaveLength(3);
80
- expect(getWalletsByChainId).toHaveLength(2);
81
- expect(getWalletsBySigningProviderId).toHaveLength(2);
82
- expect(getWalletsByChainIdAndSigningProviderId).toHaveLength(1);
83
- });
84
- test('should set and get primary wallet', async () => {
85
- const wallet1 = {
86
- primary: false,
87
- partyId: 'party1',
88
- hint: 'hint1',
89
- signingProviderId: 'internal',
90
- publicKey: 'publicKey',
91
- namespace: 'namespace',
92
- chainId: 'network1',
93
- };
94
- const wallet2 = {
95
- primary: false,
96
- partyId: 'party2',
97
- hint: 'hint2',
98
- signingProviderId: 'internal',
99
- publicKey: 'publicKey',
100
- namespace: 'namespace',
101
- chainId: 'network1',
102
- };
103
- await store.addWallet(wallet1);
104
- await store.addWallet(wallet2);
105
- await store.setPrimaryWallet('party2');
106
- const primary = await store.getPrimaryWallet();
107
- expect(primary?.partyId).toBe('party2');
108
- expect(primary?.primary).toBe(true);
109
- });
110
- test('should set and get session', async () => {
111
- const session = { network: 'net', accessToken: 'token' };
112
- await store.setSession(session);
113
- const result = await store.getSession();
114
- expect(result).toEqual(session);
115
- await store.removeSession();
116
- const removed = await store.getSession();
117
- expect(removed).toBeUndefined();
118
- });
119
- test('should add, list, get, update, and remove networks', async () => {
120
- const ledgerApi = {
121
- baseUrl: 'http://api',
122
- };
123
- const auth = {
124
- identityProviderId: 'idp1',
125
- type: 'password',
126
- issuer: 'http://auth',
127
- configUrl: 'http://auth/.well-known/openid-configuration',
128
- tokenUrl: 'http://auth',
129
- grantType: 'password',
130
- clientId: 'cid',
131
- scope: 'scope',
132
- audience: 'aud',
133
- };
134
- const network = {
135
- name: 'testnet',
136
- chainId: 'network1',
137
- synchronizerId: 'sync1::fingerprint',
138
- description: 'Test Network',
139
- ledgerApi,
140
- auth,
141
- };
142
- await store.updateNetwork(network);
143
- const listed = await store.listNetworks();
144
- expect(listed).toHaveLength(1);
145
- expect(listed[0].name).toBe('testnet');
146
- const fetched = await store.getNetwork('network1');
147
- expect(fetched.description).toBe('Test Network');
148
- await store.removeNetwork('network1');
149
- const afterRemove = await store.listNetworks();
150
- expect(afterRemove).toHaveLength(0);
151
- });
152
- test('should throw when getting a non-existent network', async () => {
153
- await expect(store.getNetwork('doesnotexist')).rejects.toThrow();
154
- });
155
- test('should throw when getting current network if none set', async () => {
156
- await expect(store.getCurrentNetwork()).rejects.toThrow();
157
- });
158
- });
159
- });
@@ -1,226 +0,0 @@
1
- // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { assertConnected, } from '@canton-network/core-wallet-auth';
4
- import { LedgerClient } from '@canton-network/core-ledger-client';
5
- import { defaultRetryableOptions } from '@canton-network/core-ledger-client/dist/ledger-api-utils';
6
- // TODO: remove AuthAware and instead provide wrapper in clients
7
- export class StoreInternal {
8
- logger;
9
- systemStorage;
10
- userStorage;
11
- authContext;
12
- constructor(config, logger, authContext, userStorage) {
13
- this.logger = logger.child({ component: 'StoreInternal' });
14
- this.systemStorage = config;
15
- this.authContext = authContext;
16
- this.userStorage = userStorage || new Map();
17
- this.syncWallets();
18
- }
19
- withAuthContext(context) {
20
- return new StoreInternal(this.systemStorage, this.logger, context, this.userStorage);
21
- }
22
- static createStorage() {
23
- return {
24
- wallets: [],
25
- transactions: new Map(),
26
- session: undefined,
27
- };
28
- }
29
- assertConnected() {
30
- return assertConnected(this.authContext).userId;
31
- }
32
- getStorage() {
33
- const userId = this.assertConnected();
34
- if (!this.userStorage.has(userId)) {
35
- this.userStorage.set(userId, StoreInternal.createStorage());
36
- }
37
- return this.userStorage.get(userId);
38
- }
39
- updateStorage(storage) {
40
- const userId = this.assertConnected();
41
- this.userStorage.set(userId, storage);
42
- }
43
- // Wallet methods
44
- async syncWallets() {
45
- try {
46
- const network = await this.getCurrentNetwork();
47
- // Get existing parties from participant
48
- const ledgerClient = new LedgerClient(new URL(network.ledgerApi.baseUrl), this.authContext.accessToken, this.logger);
49
- const rights = await ledgerClient.getWithRetry('/v2/users/{user-id}/rights', defaultRetryableOptions, {
50
- path: {
51
- 'user-id': this.authContext.userId,
52
- },
53
- });
54
- const parties = rights.rights
55
- ?.filter((right) => 'CanActAs' in right.kind)
56
- .map((right) => {
57
- if ('CanActAs' in right.kind) {
58
- return right.kind.CanActAs.value.party;
59
- }
60
- throw new Error('Unexpected right kind');
61
- });
62
- // Merge Wallets
63
- const existingWallets = await this.getWallets();
64
- const existingPartyIds = new Set(existingWallets.map((w) => w.partyId));
65
- const participantWallets = parties
66
- ?.filter((party) => !existingPartyIds.has(party)
67
- // todo: filter on idp id
68
- )
69
- .map((party) => {
70
- const [hint, namespace] = party.split('::');
71
- return {
72
- primary: false,
73
- partyId: party,
74
- hint: hint,
75
- publicKey: namespace,
76
- namespace: namespace,
77
- chainId: network.chainId,
78
- signingProviderId: 'participant', // todo: determine based on partyDetails.isLocal
79
- };
80
- }) || [];
81
- const storage = this.getStorage();
82
- const wallets = [...storage.wallets, ...participantWallets];
83
- // Set primary wallet if none exists
84
- const hasPrimary = wallets.some((w) => w.primary);
85
- if (!hasPrimary && wallets.length > 0) {
86
- wallets[0].primary = true;
87
- }
88
- this.logger.debug(wallets, 'Wallets synchronized');
89
- // Update storage with new wallets
90
- storage.wallets = wallets;
91
- this.updateStorage(storage);
92
- }
93
- catch {
94
- return;
95
- }
96
- }
97
- async getWallets(filter = {}) {
98
- const { chainIds, signingProviderIds } = filter;
99
- const chainIdSet = chainIds ? new Set(chainIds) : null;
100
- const signingProviderIdSet = signingProviderIds
101
- ? new Set(signingProviderIds)
102
- : null;
103
- return this.getStorage().wallets.filter((wallet) => {
104
- const matchedChainIds = chainIdSet
105
- ? chainIdSet.has(wallet.chainId)
106
- : true;
107
- const matchedStorageProviderIdS = signingProviderIdSet
108
- ? signingProviderIdSet.has(wallet.signingProviderId)
109
- : true;
110
- return matchedChainIds && matchedStorageProviderIdS;
111
- });
112
- }
113
- async getPrimaryWallet() {
114
- const wallets = await this.getWallets();
115
- return wallets.find((w) => w.primary === true);
116
- }
117
- async setPrimaryWallet(partyId) {
118
- const storage = this.getStorage();
119
- if (!storage.wallets.some((w) => w.partyId === partyId)) {
120
- throw new Error(`Wallet with partyId "${partyId}" not found`);
121
- }
122
- const wallets = storage.wallets.map((w) => {
123
- if (w.partyId === partyId) {
124
- w.primary = true;
125
- }
126
- else {
127
- w.primary = false;
128
- }
129
- return w;
130
- });
131
- storage.wallets = wallets;
132
- this.updateStorage(storage);
133
- }
134
- async addWallet(wallet) {
135
- const storage = this.getStorage();
136
- if (storage.wallets.some((w) => w.partyId === wallet.partyId)) {
137
- throw new Error(`Wallet with partyId "${wallet.partyId}" already exists`);
138
- }
139
- const wallets = await this.getWallets();
140
- if (wallets.length === 0) {
141
- // If this is the first wallet, set it as primary automatically
142
- wallet.primary = true;
143
- }
144
- if (wallet.primary) {
145
- // If the new wallet is primary, set all others to non-primary
146
- storage.wallets.map((w) => (w.primary = false));
147
- }
148
- wallets.push(wallet);
149
- storage.wallets = wallets;
150
- this.updateStorage(storage);
151
- }
152
- // Session methods
153
- async getSession() {
154
- return this.getStorage().session;
155
- }
156
- async setSession(session) {
157
- const storage = this.getStorage();
158
- storage.session = session;
159
- this.updateStorage(storage);
160
- }
161
- async removeSession() {
162
- const storage = this.getStorage();
163
- storage.session = undefined;
164
- this.updateStorage(storage);
165
- }
166
- // Network methods
167
- async getNetwork(chainId) {
168
- this.assertConnected();
169
- const networks = await this.listNetworks();
170
- if (!networks)
171
- throw new Error('No networks available');
172
- const network = networks.find((n) => n.chainId === chainId);
173
- if (!network)
174
- throw new Error(`Network "${chainId}" not found`);
175
- return network;
176
- }
177
- async getCurrentNetwork() {
178
- const session = this.getStorage().session;
179
- if (!session) {
180
- throw new Error('No session found');
181
- }
182
- const chainId = session.network;
183
- if (!chainId) {
184
- throw new Error('No current network set in session');
185
- }
186
- const networks = await this.listNetworks();
187
- const network = networks.find((n) => n.chainId === chainId);
188
- if (!network) {
189
- throw new Error(`Network "${chainId}" not found`);
190
- }
191
- return network;
192
- }
193
- async listNetworks() {
194
- return this.systemStorage.networks;
195
- }
196
- async updateNetwork(network) {
197
- this.assertConnected();
198
- this.removeNetwork(network.chainId); // Ensure no duplicates
199
- this.systemStorage.networks.push(network);
200
- }
201
- async addNetwork(network) {
202
- const networkAlreadyExists = this.systemStorage.networks.find((n) => n.chainId === network.chainId);
203
- if (networkAlreadyExists) {
204
- throw new Error(`Network ${network.chainId} already exists`);
205
- }
206
- else {
207
- this.systemStorage.networks.push(network);
208
- }
209
- }
210
- async removeNetwork(chainId) {
211
- this.assertConnected();
212
- this.systemStorage.networks = this.systemStorage.networks.filter((n) => n.chainId !== chainId);
213
- }
214
- // Transaction methods
215
- async setTransaction(transaction) {
216
- this.assertConnected();
217
- const storage = this.getStorage();
218
- storage.transactions.set(transaction.commandId, transaction);
219
- this.updateStorage(storage);
220
- }
221
- async getTransaction(commandId) {
222
- this.assertConnected();
223
- const storage = this.getStorage();
224
- return storage.transactions.get(commandId);
225
- }
226
- }