@tari-project/ootle-wallet-daemon-signer 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { JrpcPermission } from '@tari-project/ootle-ts-bindings';
1
+ import { Permission } from '@tari-project/ootle-ts-bindings';
2
2
  import { Signer } from '@tari-project/ootle';
3
3
  import { TransactionSignature } from '@tari-project/ootle-ts-bindings';
4
4
  import { UnsignedTransactionV1 } from '@tari-project/ootle-ts-bindings';
@@ -23,7 +23,7 @@ export declare function authenticate(client: WalletDaemonClient, options?: AuthO
23
23
 
24
24
  export declare interface AuthOptions {
25
25
  /** Permissions to request from the wallet daemon. Defaults to `["Admin"]`. */
26
- permissions?: JrpcPermission[];
26
+ permissions?: Permission[];
27
27
  /** Application name used as the WebAuthn username/identifier. Defaults to `"tari-wallet-sdk"`. */
28
28
  appName?: string;
29
29
  }
@@ -76,9 +76,10 @@ export declare class WalletDaemonSigner implements Signer {
76
76
  * engine rejects the envelope.
77
77
  *
78
78
  * TODO(daemon): the `transactions.sign` JRPC's acceptance of `seal_public_key` is unverified
79
- * against a running `tari_ootle_walletd`, and there is no capability/version handshake on the
80
- * typed client (v1.14.0 exposes only the generic `sendRequest`) to feature-detect support, so
81
- * this call cannot fail fast the way {@link getViewSecret} does. If the daemon ignores the
79
+ * against a running `tari_ootle_walletd`, and the daemon advertises no capability signal for
80
+ * it. (`walletGetInfo` returns a daemon `version` string, but nothing maps a version to
81
+ * "honours `seal_public_key`", so it cannot answer this question.) This call therefore cannot
82
+ * fail fast the way {@link getViewSecret} does. If the daemon ignores the
82
83
  * parameter and hashes with its own pk, the per-signer signatures will not verify and the
83
84
  * failure surfaces only LATE — at submit time — as the opaque engine error
84
85
  * `"Transaction has one or more invalid signature(s)"`, not here. An unconditional throw is
package/dist/index.js CHANGED
@@ -2,56 +2,72 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { SignerError as e, assertByteLength as t, fromHexStr as n, toHexStr as r } from "@tari-project/ootle";
5
- BigInt.prototype.toJSON = function() {
6
- return this > BigInt(2 ** 53 - 1) ? this.toString() : Number(this);
7
- };
8
- var i = class e2 {
9
- constructor(e4) {
5
+ function i(e4) {
6
+ return JSON.stringify(e4, a);
7
+ }
8
+ function a(e4, t2) {
9
+ return typeof t2 == "bigint" ? t2.toString() : t2;
10
+ }
11
+ var o = class e2 {
12
+ constructor(e4, t2) {
10
13
  __publicField(this, "url");
11
- this.url = e4;
14
+ __publicField(this, "credentials");
15
+ this.url = e4, this.credentials = (t2 == null ? void 0 : t2.credentials) ?? "same-origin";
12
16
  }
13
- static new(t2) {
14
- return new e2(t2);
17
+ static new(t2, n2) {
18
+ return new e2(t2, n2);
15
19
  }
16
20
  async sendRequest(e4, t2) {
17
21
  let n2 = { "Content-Type": "application/json" };
18
22
  (t2 == null ? void 0 : t2.token) && (n2.Authorization = `Bearer ${t2.token}`);
19
- let r2 = new AbortController(), i3 = r2.signal, a2 = (t2 == null ? void 0 : t2.timeout_millis) ? setTimeout(() => {
23
+ let r2 = new AbortController(), a2 = r2.signal, o2 = (t2 == null ? void 0 : t2.timeout_millis) ? setTimeout(() => {
20
24
  r2.abort("Timeout");
21
- }, t2.timeout_millis) : null, o2 = await fetch(this.url, {
25
+ }, t2.timeout_millis) : null, s2 = await fetch(this.url, {
22
26
  method: "POST",
23
- body: JSON.stringify(e4),
27
+ body: i(e4),
24
28
  headers: n2,
25
- signal: i3
29
+ credentials: this.credentials,
30
+ signal: a2
26
31
  });
27
- if (a2 && clearTimeout(a2), !o2.ok) {
28
- let e5 = await o2.text();
29
- throw Error(`HTTP error ${o2.status}: ${e5}`);
32
+ if (o2 && clearTimeout(o2), !s2.ok) {
33
+ let e5 = await s2.text();
34
+ throw Error(`HTTP error ${s2.status}: ${e5}`);
30
35
  }
31
- return await o2.json();
36
+ return await s2.json();
32
37
  }
33
- }, a = class e3 {
38
+ }, s = "tw_";
39
+ function c(e4) {
40
+ return e4.startsWith(s);
41
+ }
42
+ var l = class e3 {
34
43
  constructor(e4) {
35
44
  __publicField(this, "token");
36
45
  __publicField(this, "transport");
37
46
  __publicField(this, "id");
38
47
  __publicField(this, "reauthEnabled", true);
48
+ __publicField(this, "hasWarnedApiKeyReauth", false);
39
49
  this.token = null, this.transport = e4, this.id = 0;
40
50
  }
41
51
  static new(t2) {
42
52
  return new e3(t2);
43
53
  }
44
- static usingFetchTransport(t2) {
45
- return e3.new(i.new(t2));
54
+ static usingFetchTransport(t2, n2) {
55
+ return e3.new(o.new(t2, n2));
46
56
  }
47
57
  setReauthenticationEnabled(e4) {
48
- this.reauthEnabled = e4;
58
+ this.reauthEnabled = e4, this.warnIfApiKeyReauth();
49
59
  }
50
60
  isAuthenticated() {
51
61
  return !!this.token;
52
62
  }
53
63
  setToken(e4) {
54
- this.token = e4;
64
+ this.token = e4, this.warnIfApiKeyReauth();
65
+ }
66
+ clearToken() {
67
+ this.token = null, this.hasWarnedApiKeyReauth = false;
68
+ }
69
+ warnIfApiKeyReauth() {
70
+ this.hasWarnedApiKeyReauth || !this.reauthEnabled || !this.token || !c(this.token) || (this.hasWarnedApiKeyReauth = true, console.warn("WalletDaemonClient: reauthentication is enabled but the credential is an API key. API keys cannot be refreshed; a 401 means the key is revoked, expired, or lacks the required permission."));
55
71
  }
56
72
  getToken() {
57
73
  return this.token;
@@ -78,6 +94,36 @@ var i = class e2 {
78
94
  authRefresh() {
79
95
  return this.sendRequest("auth.refresh");
80
96
  }
97
+ transactionRequestsCreate(e4) {
98
+ return this.sendRequest("transaction_requests.create", e4);
99
+ }
100
+ transactionRequestsGet(e4) {
101
+ return this.sendRequest("transaction_requests.get", e4);
102
+ }
103
+ transactionRequestsList(e4 = { status: null }) {
104
+ return this.sendRequest("transaction_requests.list", e4);
105
+ }
106
+ transactionRequestsApprove(e4) {
107
+ return this.sendRequest("transaction_requests.approve", e4);
108
+ }
109
+ transactionRequestsReject(e4) {
110
+ return this.sendRequest("transaction_requests.reject", e4);
111
+ }
112
+ transactionRequestsSubmit(e4) {
113
+ return this.sendRequest("transaction_requests.submit", e4);
114
+ }
115
+ authCreateApiKey(e4) {
116
+ return this.sendRequest("auth.create_api_key", e4);
117
+ }
118
+ authListApiKeys(e4 = { include_revoked: false }) {
119
+ return this.sendRequest("auth.list_api_keys", e4);
120
+ }
121
+ authRevokeApiKey(e4) {
122
+ return this.sendRequest("auth.revoke_api_key", e4);
123
+ }
124
+ authenticateWithApiKey(e4) {
125
+ this.setToken(e4);
126
+ }
81
127
  walletGetInfo() {
82
128
  return this.sendRequest("wallet.get_info", {});
83
129
  }
@@ -90,6 +136,9 @@ var i = class e2 {
90
136
  burnProofsList(e4) {
91
137
  return this.sendRequest("burn_proofs.list", e4);
92
138
  }
139
+ burnProofsGet(e4) {
140
+ return this.sendRequest("burn_proofs.get", e4);
141
+ }
93
142
  accountsClaimBurn(e4) {
94
143
  return this.sendRequest("accounts.claim_burn", e4);
95
144
  }
@@ -99,6 +148,9 @@ var i = class e2 {
99
148
  accountsGetBalances(e4) {
100
149
  return this.sendRequest("accounts.get_balances", e4);
101
150
  }
151
+ accountsGetBalanceChanges(e4) {
152
+ return this.sendRequest("accounts.get_balance_changes", e4);
153
+ }
102
154
  accountsList(e4) {
103
155
  return this.sendRequest("accounts.list", e4);
104
156
  }
@@ -126,6 +178,9 @@ var i = class e2 {
126
178
  submitTransactionDryRun(e4) {
127
179
  return this.sendRequest("transactions.submit_dry_run", e4);
128
180
  }
181
+ transactionsDetectInputs(e4) {
182
+ return this.sendRequest("transactions.detect_inputs", e4);
183
+ }
129
184
  submitTransactionManifest(e4) {
130
185
  return this.sendRequest("transactions.submit_manifest", e4);
131
186
  }
@@ -138,6 +193,12 @@ var i = class e2 {
138
193
  substatesList(e4) {
139
194
  return this.sendRequest("substates.list", e4);
140
195
  }
196
+ swapPoolGetExchangeRate(e4) {
197
+ return this.sendRequest("swap_pools.get_exchange_rate", e4);
198
+ }
199
+ swapPoolsList(e4) {
200
+ return this.sendRequest("swap_pools.list", e4);
201
+ }
141
202
  transactionsList(e4) {
142
203
  return this.sendRequest("transactions.list", e4);
143
204
  }
@@ -210,9 +271,27 @@ var i = class e2 {
210
271
  stealthUtxosList(e4) {
211
272
  return this.sendRequest("stealth_utxos.list", e4);
212
273
  }
274
+ confidentialListOutputs(e4) {
275
+ return this.sendRequest("confidential.list_outputs", e4);
276
+ }
213
277
  stealthUtxosDecryptValue(e4) {
214
278
  return this.sendRequest("stealth_utxos.decrypt_value", e4);
215
279
  }
280
+ addressBookAdd(e4) {
281
+ return this.sendRequest("address_book.add", e4);
282
+ }
283
+ addressBookList() {
284
+ return this.sendRequest("address_book.list", {});
285
+ }
286
+ addressBookGet(e4) {
287
+ return this.sendRequest("address_book.get", e4);
288
+ }
289
+ addressBookUpdate(e4) {
290
+ return this.sendRequest("address_book.update", e4);
291
+ }
292
+ addressBookDelete(e4) {
293
+ return this.sendRequest("address_book.delete", e4);
294
+ }
216
295
  async sendRequest(e4, t2 = null) {
217
296
  let n2 = this.id++, r2 = await this.transport.sendRequest({
218
297
  method: e4,
@@ -235,14 +314,15 @@ var i = class e2 {
235
314
  method: e4,
236
315
  ...r2.error
237
316
  } });
238
- if (e4.startsWith("auth.")) throw console.warn("Token refresh failed"), this.token = null, n3;
317
+ if (e4.startsWith("auth.")) throw console.warn("Token refresh failed"), this.clearToken(), n3;
318
+ if (this.token && c(this.token)) throw n3;
239
319
  let i3 = this.id++, a2 = await this.transport.sendRequest({
240
320
  method: "auth.refresh",
241
321
  jsonrpc: "2.0",
242
322
  id: i3,
243
323
  params: {}
244
324
  });
245
- if (a2.error) throw console.debug("Refresh resp", a2), this.token = null, n3;
325
+ if (a2.error) throw console.debug("Refresh resp", a2), this.clearToken(), n3;
246
326
  console.debug("Token refreshed successfully. Retrying original request."), this.token = a2.result.token, r2 = await this.transport.sendRequest({
247
327
  method: e4,
248
328
  jsonrpc: "2.0",
@@ -259,55 +339,55 @@ var i = class e2 {
259
339
  } });
260
340
  return r2.result;
261
341
  }
262
- }, o = "tari-wallet-sdk", s = ["Admin"];
263
- function c(e4) {
342
+ }, u = "tari-wallet-sdk", d = ["Admin"];
343
+ function f(e4) {
264
344
  let t2 = e4.replace(/-/g, "+").replace(/_/g, "/"), n2 = t2.padEnd(Math.ceil(t2.length / 4) * 4, "=");
265
345
  return Uint8Array.from(atob(n2), (e5) => e5.charCodeAt(0));
266
346
  }
267
- async function l(t2, n2) {
268
- let r2 = (n2 == null ? void 0 : n2.permissions) ?? s, i3 = (n2 == null ? void 0 : n2.appName) ?? o, { method: a2 } = await t2.authGetMethod();
347
+ async function p(t2, n2) {
348
+ let r2 = (n2 == null ? void 0 : n2.permissions) ?? d, i3 = (n2 == null ? void 0 : n2.appName) ?? u, { method: a2 } = await t2.authGetMethod();
269
349
  switch (a2) {
270
350
  case "none":
271
351
  return t2.authRequest(r2, "None");
272
352
  case "webauthn":
273
- return u(t2, i3, r2);
353
+ return m(t2, i3, r2);
274
354
  default:
275
355
  throw new e(`Unsupported wallet daemon auth method: ${a2}. Configure the daemon for one of: "none" or "webauthn", and pass that value to WalletDaemonSigner.connect.`);
276
356
  }
277
357
  }
278
- async function u(t2, n2, r2) {
358
+ async function m(t2, n2, r2) {
279
359
  if (globalThis.navigator === void 0 || !globalThis.navigator.credentials) throw new e("WebAuthn is browser-only. Run in a browser, or pass `authToken` explicitly to `WalletDaemonSigner.connect({ url, authToken })` from Node.");
280
360
  let { registered: i3 } = await t2.webauthnAlreadyRegistered({ username: n2 });
281
- return i3 ? d(t2, n2, r2) : f(t2, n2, r2);
361
+ return i3 ? h(t2, n2, r2) : g(t2, n2, r2);
282
362
  }
283
- async function d(t2, n2, r2) {
363
+ async function h(t2, n2, r2) {
284
364
  var _a;
285
365
  let i3 = await t2.webauthnAuthStart({ username: n2 });
286
366
  if (!i3.challenge) throw new e("WebAuthn auth start: missing challenge");
287
367
  let a2 = i3.challenge;
288
368
  if (!((_a = a2.publicKey) == null ? void 0 : _a.challenge)) throw new e("WebAuthn auth start: malformed challenge response");
289
- let { publicKey: o2 } = a2, s2 = c(o2.challenge), l2 = (o2.allowCredentials ?? []).map((e4) => ({
290
- id: c(e4.id),
369
+ let { publicKey: o2 } = a2, s2 = f(o2.challenge), c2 = (o2.allowCredentials ?? []).map((e4) => ({
370
+ id: f(e4.id),
291
371
  type: e4.type
292
- })), u2 = await navigator.credentials.get({ publicKey: {
372
+ })), l2 = await navigator.credentials.get({ publicKey: {
293
373
  challenge: s2,
294
- allowCredentials: l2,
374
+ allowCredentials: c2,
295
375
  timeout: 6e4,
296
376
  userVerification: "required"
297
377
  } });
298
- if (!u2) throw new e("WebAuthn authentication was cancelled");
378
+ if (!l2) throw new e("WebAuthn authentication was cancelled");
299
379
  return t2.authRequest(r2, { WebAuthN: {
300
380
  session_id: i3.session_id,
301
- credential: u2
381
+ credential: l2
302
382
  } });
303
383
  }
304
- async function f(t2, n2, r2) {
384
+ async function g(t2, n2, r2) {
305
385
  var _a, _b, _c;
306
386
  let i3 = await t2.webauthnStartRegistration({ username: n2 });
307
387
  if (!i3.public_key) throw new e("WebAuthn registration start: missing public_key");
308
388
  let a2 = i3.public_key;
309
389
  if (!a2.challenge) throw new e("WebAuthn registration start: malformed public_key response");
310
- let o2 = c(a2.challenge), s2 = await navigator.credentials.create({ publicKey: {
390
+ let o2 = f(a2.challenge), s2 = await navigator.credentials.create({ publicKey: {
311
391
  rp: {
312
392
  name: ((_a = a2.rp) == null ? void 0 : _a.name) ?? "Tari Wallet",
313
393
  id: ((_b = a2.rp) == null ? void 0 : _b.id) ?? ((_c = globalThis.location) == null ? void 0 : _c.hostname)
@@ -338,14 +418,14 @@ async function f(t2, n2, r2) {
338
418
  authenticatorSelection: { userVerification: "required" }
339
419
  } });
340
420
  if (!s2) throw new e("WebAuthn registration was cancelled");
341
- let { token: l2 } = await t2.webauthnFinishRegistration({
421
+ let { token: c2 } = await t2.webauthnFinishRegistration({
342
422
  session_id: i3.session_id,
343
423
  credential: s2,
344
424
  requested_permissions: r2
345
425
  });
346
- return l2;
426
+ return c2;
347
427
  }
348
- var p = class i2 {
428
+ var _ = class i2 {
349
429
  constructor(e4) {
350
430
  __publicField(this, "client");
351
431
  __publicField(this, "_publicKey", null);
@@ -353,14 +433,14 @@ var p = class i2 {
353
433
  this.client = e4;
354
434
  }
355
435
  static new(e4) {
356
- let t2 = a.usingFetchTransport(e4.url);
436
+ let t2 = l.usingFetchTransport(e4.url);
357
437
  return t2.setToken(e4.authToken), new i2(t2);
358
438
  }
359
439
  static async connect(e4) {
360
- let t2 = a.usingFetchTransport(e4.url);
440
+ let t2 = l.usingFetchTransport(e4.url);
361
441
  if (e4.authToken) t2.setToken(e4.authToken);
362
442
  else {
363
- let n3 = await l(t2, e4);
443
+ let n3 = await p(t2, e4);
364
444
  t2.setToken(n3);
365
445
  }
366
446
  t2.setReauthenticationEnabled(true);
@@ -401,7 +481,7 @@ var p = class i2 {
401
481
  }
402
482
  };
403
483
  export {
404
- a as WalletDaemonClient,
405
- p as WalletDaemonSigner,
406
- l as authenticate
484
+ l as WalletDaemonClient,
485
+ _ as WalletDaemonSigner,
486
+ p as authenticate
407
487
  };
package/package.json CHANGED
@@ -1,6 +1,14 @@
1
1
  {
2
2
  "name": "@tari-project/ootle-wallet-daemon-signer",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/tari-project/ootle.ts.git",
7
+ "directory": "packages/ootle-wallet-daemon-signer"
8
+ },
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
4
12
  "type": "module",
5
13
  "main": "./dist/index.js",
6
14
  "types": "./dist/index.d.ts",
@@ -17,9 +25,9 @@
17
25
  }
18
26
  },
19
27
  "dependencies": {
20
- "@tari-project/ootle-ts-bindings": "^1.30.0",
21
- "@tari-project/wallet_jrpc_client": "^1.14.0",
22
- "@tari-project/ootle": "0.1.0"
28
+ "@tari-project/ootle-ts-bindings": "^1.49.1",
29
+ "@tari-project/wallet_jrpc_client": "^1.22.0",
30
+ "@tari-project/ootle": "0.3.0"
23
31
  },
24
32
  "devDependencies": {
25
33
  "@microsoft/api-extractor": "^7.57.7",