@canton-network/wallet-gateway-remote 0.1.0 → 0.2.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/README.md CHANGED
@@ -4,7 +4,17 @@ The RPC-based (server-side) Wallet Gateway.
4
4
 
5
5
  # Usage
6
6
 
7
- Start the service directly through npx (tested with NodeJS v24):
7
+ Install the Wallet Gateway
8
+
9
+ ```shell
10
+ $ npm install -g @canton-network/wallet-gateway-remote
11
+
12
+ ...
13
+
14
+ $ wallet-gateway -c ./config.json
15
+ ```
16
+
17
+ Alternatively, you can run it directly through npx (tested with NodeJS v24):
8
18
 
9
19
  `npx @canton-network/wallet-gateway-remote -c ./config.json`
10
20
 
@@ -16,7 +26,19 @@ This exposes:
16
26
 
17
27
  ## Configuration
18
28
 
19
- A configuration file is required to start up the gateway. See [config.json](https://github.com/hyperledger-labs/splice-wallet-kernel/blob/main/wallet-gateway/test/config.json) for an example.
29
+ A configuration file is required to start up the Gateway. See [config.json](https://github.com/hyperledger-labs/splice-wallet-kernel/blob/main/wallet-gateway/test/config.json) for an example.
30
+
31
+ ## First time startup
32
+
33
+ When running the Gateway for the first time, the database must be properly initialized.
34
+
35
+ ```shell
36
+ $ wallet-gateway -c ./config.json db reset
37
+ $ wallet-gateway -c ./config.json db bootstrap
38
+
39
+ # Finally, start the service
40
+ $ wallet-gateway -c ./config.json
41
+ ```
20
42
 
21
43
  # Developing
22
44
 
@@ -17,7 +17,7 @@ async function prepareSubmission(userId, partyId, synchronizerId, commands, ledg
17
17
  verboseHashing: false,
18
18
  packageIdSelectionPreference: [],
19
19
  };
20
- return await ledgerClient.post('/v2/interactive-submission/prepare', prepareParams);
20
+ return await ledgerClient.postWithRetry('/v2/interactive-submission/prepare', prepareParams);
21
21
  }
22
22
  export const dappController = (kernelInfo, store, notificationService, _logger, context) => {
23
23
  const logger = _logger.child({ component: 'dapp-controller' });
package/dist/index.js CHANGED
@@ -5,13 +5,20 @@ import { Option, Command } from '@commander-js/extra-typings';
5
5
  import { initialize } from './init.js';
6
6
  import { createCLI } from '@canton-network/core-wallet-store-sql';
7
7
  import { ConfigUtils } from './config/ConfigUtils.js';
8
+ import { readFileSync } from 'fs';
9
+ import { join, dirname } from 'path';
10
+ import { fileURLToPath } from 'url';
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+ const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
8
14
  const program = new Command()
9
- .name('wallet-gateway-remote')
15
+ .name('wallet-gateway')
16
+ .version(pkg.version)
10
17
  .description('Run a remotely hosted Wallet Gateway')
11
- .option('-c, --config <path>', 'set config path', '../test/config.json')
18
+ .option('-c, --config <path>', 'set config path', './config.json')
12
19
  .addOption(new Option('-f, --log-format <format>', 'set log format')
13
20
  .choices(['json', 'pretty'])
14
- .default('json'))
21
+ .default('pretty'))
15
22
  .addOption(new Option('-s, --store-type <type>', 'set store type')
16
23
  .choices(['sqlite', 'postgres'])
17
24
  .default('sqlite'))
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAmDA,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,QAAQ,GAAG,MAAM,CAAA;CAC/B;;;;GA4EA"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAmDA,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,QAAQ,GAAG,MAAM,CAAA;CAC/B;;;;GAkEA"}
package/dist/init.js CHANGED
@@ -52,10 +52,7 @@ export async function initialize(opts) {
52
52
  : {}),
53
53
  });
54
54
  const notificationService = new NotificationService(logger);
55
- // TODO: make the default config path point to ${PWD}/config.json
56
- const defaultConfig = path.join(dirname(fileURLToPath(import.meta.url)), '..', 'test', 'config.json');
57
- const configPath = opts.config || defaultConfig;
58
- const config = ConfigUtils.loadConfigFile(configPath);
55
+ const config = ConfigUtils.loadConfigFile(opts.config);
59
56
  const store = new StoreSql(connection(config.store), logger);
60
57
  const authService = jwtAuthService(store, logger);
61
58
  const drivers = {
@@ -1 +1 @@
1
- {"version":3,"file":"party-allocation-service.d.ts","sourceRoot":"","sources":["../../src/ledger/party-allocation-service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAE7B,MAAM,MAAM,cAAc,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAEpD;;GAEG;AACH,qBAAa,sBAAsB;IAI3B,OAAO,CAAC,cAAc;IAGtB,OAAO,CAAC,MAAM;IANlB,OAAO,CAAC,YAAY,CAAc;gBAGtB,cAAc,EAAE,MAAM,EAC9B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;IAS1B;;;;OAIG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAE1E;;;;;;OAMG;IACG,aAAa,CACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,WAAW,GAC7B,OAAO,CAAC,cAAc,CAAC;YAoBZ,qBAAqB;YAqBrB,qBAAqB;CAmCtC"}
1
+ {"version":3,"file":"party-allocation-service.d.ts","sourceRoot":"","sources":["../../src/ledger/party-allocation-service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAE7B,MAAM,MAAM,cAAc,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAEpD;;GAEG;AACH,qBAAa,sBAAsB;IAI3B,OAAO,CAAC,cAAc;IAGtB,OAAO,CAAC,MAAM;IANlB,OAAO,CAAC,YAAY,CAAc;gBAGtB,cAAc,EAAE,MAAM,EAC9B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;IAS1B;;;;OAIG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAE1E;;;;;;OAMG;IACG,aAAa,CACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,WAAW,GAC7B,OAAO,CAAC,cAAc,CAAC;YAoBZ,qBAAqB;YAoBrB,qBAAqB;CAmCtC"}
@@ -19,8 +19,8 @@ export class PartyAllocationService {
19
19
  }
20
20
  }
21
21
  async allocateInternalParty(userId, hint) {
22
- const { participantId: namespace } = await this.ledgerClient.get('/v2/parties/participant-id');
23
- const res = await this.ledgerClient.post('/v2/parties', {
22
+ const { participantId: namespace } = await this.ledgerClient.getWithRetry('/v2/parties/participant-id');
23
+ const res = await this.ledgerClient.postWithRetry('/v2/parties', {
24
24
  partyIdHint: hint,
25
25
  identityProviderId: '',
26
26
  });
@@ -20,8 +20,8 @@ jest.unstable_mockModule('@canton-network/core-ledger-client', () => ({
20
20
  SignedTopologyTransaction: jest.fn(),
21
21
  LedgerClient: jest.fn().mockImplementation(() => {
22
22
  return {
23
- get: mockLedgerGet,
24
- post: mockLedgerPost,
23
+ getWithRetry: mockLedgerGet,
24
+ postWithRetry: mockLedgerPost,
25
25
  grantUserRights: mockLedgerGrantUserRights,
26
26
  generateTopology: jest.fn().mockResolvedValue({
27
27
  partyId: 'party2::mypublickey',
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-sync-service.d.ts","sourceRoot":"","sources":["../../src/ledger/wallet-sync-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAE7B,MAAM,MAAM,gBAAgB,GAAG;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;CACpB,CAAA;AACD,qBAAa,iBAAiB;IAEtB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;gBAHN,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM;IAGpB,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrC,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC;CA6FjD"}
1
+ {"version":3,"file":"wallet-sync-service.d.ts","sourceRoot":"","sources":["../../src/ledger/wallet-sync-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAE7B,MAAM,MAAM,gBAAgB,GAAG;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;CACpB,CAAA;AACD,qBAAa,iBAAiB;IAEtB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;gBAHN,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM;IAGpB,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrC,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC;CA8FjD"}
@@ -1,5 +1,6 @@
1
1
  // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
+ import { defaultRetryableOptions } from '@canton-network/core-ledger-client/dist/ledger-api-utils.js';
3
4
  export class WalletSyncService {
4
5
  constructor(store, ledgerClient, authContext, logger) {
5
6
  this.store = store;
@@ -20,7 +21,7 @@ export class WalletSyncService {
20
21
  const network = await this.store.getCurrentNetwork();
21
22
  this.logger.info(network, 'Current network');
22
23
  // Get existing parties from participant
23
- const rights = await this.ledgerClient.get('/v2/users/{user-id}/rights', {
24
+ const rights = await this.ledgerClient.getWithRetry('/v2/users/{user-id}/rights', defaultRetryableOptions, {
24
25
  path: {
25
26
  'user-id': this.authContext.userId,
26
27
  },
@@ -217,7 +217,7 @@ export const userController = (kernelInfo, store, notificationService, authConte
217
217
  packageIdSelectionPreference: [],
218
218
  };
219
219
  try {
220
- const res = await ledgerClient.post('/v2/commands/submit-and-wait', request);
220
+ const res = await ledgerClient.postWithRetry('/v2/commands/submit-and-wait', request);
221
221
  notifier.emit('txChanged', {
222
222
  status: 'executed',
223
223
  commandId,
@@ -230,7 +230,7 @@ export const userController = (kernelInfo, store, notificationService, authConte
230
230
  }
231
231
  }
232
232
  case SigningProvider.WALLET_KERNEL: {
233
- const result = await ledgerClient.post('/v2/interactive-submission/execute', {
233
+ const result = await ledgerClient.postWithRetry('/v2/interactive-submission/execute', {
234
234
  userId,
235
235
  preparedTransaction: transaction.preparedTransaction,
236
236
  hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V2',
@@ -3,10 +3,10 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <title>Wallet Kernel - Not found</title>
6
- <script type="module" crossorigin src="/assets/404-BHkjVWlW.js"></script>
6
+ <script type="module" crossorigin src="/assets/404-FxmR286l.js"></script>
7
7
  <link rel="modulepreload" crossorigin href="/assets/state-manager-BNW0y5PZ.js">
8
- <link rel="modulepreload" crossorigin href="/assets/index-D-GexOrJ.js">
9
- <link rel="modulepreload" crossorigin href="/assets/index-BxdGgjHv.js">
8
+ <link rel="modulepreload" crossorigin href="/assets/index-VtAAU1cN.js">
9
+ <link rel="modulepreload" crossorigin href="/assets/index-BPTkodPz.js">
10
10
  <link rel="stylesheet" crossorigin href="/assets/index-TZrNw7dA.css">
11
11
  <link rel="stylesheet" crossorigin href="/assets/index-BknZMPaI.css">
12
12
  </head>
@@ -3,10 +3,10 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <title>Wallet Kernel - Approve Write Request</title>
6
- <script type="module" crossorigin src="/assets/approve-lRsfAWmm.js"></script>
6
+ <script type="module" crossorigin src="/assets/approve-DjrMmUo0.js"></script>
7
7
  <link rel="modulepreload" crossorigin href="/assets/state-manager-BNW0y5PZ.js">
8
- <link rel="modulepreload" crossorigin href="/assets/index-D-GexOrJ.js">
9
- <link rel="modulepreload" crossorigin href="/assets/index-BxdGgjHv.js">
8
+ <link rel="modulepreload" crossorigin href="/assets/index-VtAAU1cN.js">
9
+ <link rel="modulepreload" crossorigin href="/assets/index-BPTkodPz.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/state-DKGJ6EmM.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/rpc-client-CCUlY3sp.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/handle-errors-BcwHAkCd.js">
@@ -1,4 +1,4 @@
1
- import{i as k,a as z,x as O,t as P}from"./state-manager-BNW0y5PZ.js";import"./index-BxdGgjHv.js";import"./index-D-GexOrJ.js";var C=Object.create,p=Object.defineProperty,E=Object.getOwnPropertyDescriptor,b=(r,e)=>(e=Symbol[r])?e:Symbol.for("Symbol."+r),h=r=>{throw TypeError(r)},I=(r,e,a)=>e in r?p(r,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):r[e]=a,j=(r,e)=>p(r,"name",{value:e,configurable:!0}),A=r=>[,,,C((r==null?void 0:r[b("metadata")])??null)],D=["class","method","getter","setter","accessor","field","value","get","set"],w=r=>r!==void 0&&typeof r!="function"?h("Function expected"):r,F=(r,e,a,i,t)=>({kind:D[r],name:e,metadata:i,addInitializer:o=>a._?h("Already initialized"):t.push(w(o||null))}),M=(r,e)=>I(e,b("metadata"),r[3]),N=(r,e,a,i)=>{for(var t=0,o=r[e>>1],n=o&&o.length;t<n;t++)o[t].call(a);return i},T=(r,e,a,i,t,o)=>{var n,u,m,l=e&7,f=!1,x=0,g=r[x]||(r[x]=[]),d=l&&(t=t.prototype,l<5&&(l>3||!f)&&E(t,a));j(t,a);for(var _=i.length-1;_>=0;_--)m=F(l,a,u={},r[3],g),n=(0,i[_])(t,m),u._=1,w(n)&&(t=n);return M(r,t),d&&p(t,a,d),f?l^4?o:d:t},y,s,S;y=[P("user-ui-404")];const v=class v extends(S=k){connectedCallback(){super.connectedCallback()}render(){return O`
1
+ import{i as k,a as z,x as O,t as P}from"./state-manager-BNW0y5PZ.js";import"./index-BPTkodPz.js";import"./index-VtAAU1cN.js";var C=Object.create,p=Object.defineProperty,E=Object.getOwnPropertyDescriptor,b=(r,e)=>(e=Symbol[r])?e:Symbol.for("Symbol."+r),h=r=>{throw TypeError(r)},I=(r,e,a)=>e in r?p(r,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):r[e]=a,j=(r,e)=>p(r,"name",{value:e,configurable:!0}),A=r=>[,,,C((r==null?void 0:r[b("metadata")])??null)],D=["class","method","getter","setter","accessor","field","value","get","set"],w=r=>r!==void 0&&typeof r!="function"?h("Function expected"):r,F=(r,e,a,i,t)=>({kind:D[r],name:e,metadata:i,addInitializer:o=>a._?h("Already initialized"):t.push(w(o||null))}),M=(r,e)=>I(e,b("metadata"),r[3]),N=(r,e,a,i)=>{for(var t=0,o=r[e>>1],n=o&&o.length;t<n;t++)o[t].call(a);return i},T=(r,e,a,i,t,o)=>{var n,u,m,l=e&7,f=!1,x=0,g=r[x]||(r[x]=[]),d=l&&(t=t.prototype,l<5&&(l>3||!f)&&E(t,a));j(t,a);for(var _=i.length-1;_>=0;_--)m=F(l,a,u={},r[3],g),n=(0,i[_])(t,m),u._=1,w(n)&&(t=n);return M(r,t),d&&p(t,a,d),f?l^4?o:d:t},y,s,S;y=[P("user-ui-404")];const v=class v extends(S=k){connectedCallback(){super.connectedCallback()}render(){return O`
2
2
  <div class="wrapper">
3
3
  <not-found />
4
4
  </div>