@sundaeswap/wallet-lite 0.0.87 → 0.0.88

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 (42) hide show
  1. package/dist/cjs/@types/observer.js.map +1 -1
  2. package/dist/cjs/classes/ReadOnlyApi.class.js +160 -0
  3. package/dist/cjs/classes/ReadOnlyApi.class.js.map +1 -0
  4. package/dist/cjs/classes/ReadOnlyProvider.Abstract.class.js +19 -0
  5. package/dist/cjs/classes/ReadOnlyProvider.Abstract.class.js.map +1 -0
  6. package/dist/cjs/classes/ReadOnlyProvider.Blockfrost.class.js +127 -0
  7. package/dist/cjs/classes/ReadOnlyProvider.Blockfrost.class.js.map +1 -0
  8. package/dist/cjs/classes/WalletObserver.class.js +65 -45
  9. package/dist/cjs/classes/WalletObserver.class.js.map +1 -1
  10. package/dist/cjs/classes/index.js +14 -0
  11. package/dist/cjs/classes/index.js.map +1 -1
  12. package/dist/esm/@types/observer.js.map +1 -1
  13. package/dist/esm/classes/ReadOnlyApi.class.js +51 -0
  14. package/dist/esm/classes/ReadOnlyApi.class.js.map +1 -0
  15. package/dist/esm/classes/ReadOnlyProvider.Abstract.class.js +10 -0
  16. package/dist/esm/classes/ReadOnlyProvider.Abstract.class.js.map +1 -0
  17. package/dist/esm/classes/ReadOnlyProvider.Blockfrost.class.js +64 -0
  18. package/dist/esm/classes/ReadOnlyProvider.Blockfrost.class.js.map +1 -0
  19. package/dist/esm/classes/WalletObserver.class.js +15 -3
  20. package/dist/esm/classes/WalletObserver.class.js.map +1 -1
  21. package/dist/esm/classes/index.js +2 -0
  22. package/dist/esm/classes/index.js.map +1 -1
  23. package/dist/types/@types/observer.d.ts +2 -0
  24. package/dist/types/@types/observer.d.ts.map +1 -1
  25. package/dist/types/classes/ReadOnlyApi.class.d.ts +21 -0
  26. package/dist/types/classes/ReadOnlyApi.class.d.ts.map +1 -0
  27. package/dist/types/classes/ReadOnlyProvider.Abstract.class.d.ts +5 -0
  28. package/dist/types/classes/ReadOnlyProvider.Abstract.class.d.ts.map +1 -0
  29. package/dist/types/classes/ReadOnlyProvider.Blockfrost.class.d.ts +12 -0
  30. package/dist/types/classes/ReadOnlyProvider.Blockfrost.class.d.ts.map +1 -0
  31. package/dist/types/classes/WalletObserver.class.d.ts.map +1 -1
  32. package/dist/types/classes/index.d.ts +2 -0
  33. package/dist/types/classes/index.d.ts.map +1 -1
  34. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  35. package/package.json +3 -2
  36. package/src/@types/observer.ts +2 -0
  37. package/src/classes/ReadOnlyApi.class.ts +64 -0
  38. package/src/classes/ReadOnlyProvider.Abstract.class.ts +4 -0
  39. package/src/classes/ReadOnlyProvider.Blockfrost.class.ts +87 -0
  40. package/src/classes/WalletObserver.class.ts +29 -3
  41. package/src/classes/__tests__/WalletObserver.test.ts +1 -1
  42. package/src/classes/index.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sundaeswap/wallet-lite",
3
- "version": "0.0.87",
3
+ "version": "0.0.88",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -22,7 +22,7 @@
22
22
  "LICENSE.md"
23
23
  ],
24
24
  "engines": {
25
- "node": ">=16.0.0"
25
+ "node": ">=18.0.0"
26
26
  },
27
27
  "scripts": {
28
28
  "clean": "rm -rf ./dist",
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@babel/cli": "^7.24.7",
39
+ "@blockfrost/blockfrost-js": "^6.0.0",
39
40
  "@fabianbormann/cardano-peer-connect": "^1.2.17",
40
41
  "@koralabs/adahandle-sdk": "^1.5.5",
41
42
  "@sundaeswap/asset": "^1.0.7",
@@ -4,6 +4,7 @@ import type { DAppPeerConnect } from "@fabianbormann/cardano-peer-connect";
4
4
  import type { DAppPeerConnectParameters } from "@fabianbormann/cardano-peer-connect/dist/src/types.js";
5
5
  import type { IAssetAmountMetadata } from "@sundaeswap/asset";
6
6
 
7
+ import { ReadOnlyProvider } from "src/classes/ReadOnlyProvider.Abstract.class.js";
7
8
  import { WalletAssetMap } from "../classes/WalletAssetMap.class.js";
8
9
  import { WalletBalanceMap } from "../classes/WalletBalanceMap.class.js";
9
10
  import { isAdaAsset, normalizeAssetIdWithDot } from "../utils/assets.js";
@@ -54,6 +55,7 @@ export interface IResolvedWalletObserverOptions<
54
55
  persistence: boolean;
55
56
  peerConnectArgs: DAppPeerConnectParameters;
56
57
  connectTimeout: number;
58
+ readOnlyProvider?: ReadOnlyProvider;
57
59
  debug: boolean;
58
60
  }
59
61
 
@@ -0,0 +1,64 @@
1
+ import { Cardano } from "@cardano-sdk/core";
2
+ import { Cip30WalletApi } from "@cardano-sdk/dapp-connector";
3
+
4
+ import { ReadOnlyProvider } from "./ReadOnlyProvider.Abstract.class.js";
5
+
6
+ export class ReadOnlyApi implements Cip30WalletApi {
7
+ address: string;
8
+ network: 0 | 1;
9
+ provider: ReadOnlyProvider;
10
+
11
+ constructor(address: string, network: 0 | 1, provider: ReadOnlyProvider) {
12
+ this.address = address;
13
+ this.provider = provider;
14
+ this.network = network;
15
+ }
16
+
17
+ getBalance = async () => {
18
+ return this.provider.getBalance(this.address, this.network);
19
+ };
20
+
21
+ getChangeAddress = async () => {
22
+ return Cardano.Address.fromBech32(this.address).toBytes();
23
+ };
24
+
25
+ getCollateral = async () => {
26
+ return [];
27
+ };
28
+
29
+ getExtensions = async () => {
30
+ return [];
31
+ };
32
+
33
+ getNetworkId = async () => {
34
+ return this.network;
35
+ };
36
+
37
+ getRewardAddresses = async () => {
38
+ return [];
39
+ };
40
+
41
+ getUnusedAddresses = async () => {
42
+ return [];
43
+ };
44
+
45
+ getUsedAddresses = async () => {
46
+ return [];
47
+ };
48
+
49
+ getUtxos = async () => {
50
+ return this.provider.getUtxos(this.address, this.network);
51
+ };
52
+
53
+ signData = async () => {
54
+ throw new Error("not implemented");
55
+ };
56
+
57
+ signTx = async () => {
58
+ throw new Error("not implemented");
59
+ };
60
+
61
+ submitTx = async () => {
62
+ throw new Error("not implemented");
63
+ };
64
+ }
@@ -0,0 +1,4 @@
1
+ export abstract class ReadOnlyProvider {
2
+ abstract getBalance: (address: string, network: 0 | 1) => Promise<string>;
3
+ abstract getUtxos: (address: string, network: 0 | 1) => Promise<string[]>;
4
+ }
@@ -0,0 +1,87 @@
1
+ import type { BlockFrostAPI, Responses } from "@blockfrost/blockfrost-js";
2
+ import { Cardano, Serialization } from "@cardano-sdk/core";
3
+ import { Hash32ByteBase16 } from "@cardano-sdk/crypto";
4
+
5
+ import { HexBlob } from "@cardano-sdk/util";
6
+ import { ReadOnlyProvider } from "./ReadOnlyProvider.Abstract.class.js";
7
+
8
+ export class ReadOnlyBlockfrostProvider implements ReadOnlyProvider {
9
+ blockfrostProjectId: string;
10
+ api?: BlockFrostAPI;
11
+
12
+ constructor(blockfrostProjectId: string) {
13
+ this.blockfrostProjectId = blockfrostProjectId;
14
+ }
15
+
16
+ async getBalance(address: string, network: 0 | 1) {
17
+ const result: Responses["address_content"] = await fetch(
18
+ `https://cardano-${network ? "mainnet" : "preview"}.blockfrost.io/api/v0/addresses/${address}`,
19
+ {
20
+ headers: {
21
+ project_id: this.blockfrostProjectId,
22
+ },
23
+ },
24
+ ).then((res) => res.json());
25
+
26
+ // Build our value.
27
+ const value = this.__getValueFromAmount(result.amount);
28
+
29
+ // Return the cbor.
30
+ return value.toCbor();
31
+ }
32
+
33
+ async getUtxos(address: string, network: 0 | 1) {
34
+ const result: Responses["address_utxo_content"] = await fetch(
35
+ `https://cardano-${network ? "mainnet" : "preview"}.blockfrost.io/api/v0/addresses/${address}/utxos`,
36
+ {
37
+ headers: {
38
+ project_id: this.blockfrostProjectId,
39
+ },
40
+ },
41
+ ).then((res) => res.json());
42
+
43
+ const formatted = result.map((r) => {
44
+ return Serialization.TransactionUnspentOutput.fromCore([
45
+ Serialization.TransactionInput.fromCore({
46
+ index: r.output_index,
47
+ txId: Cardano.TransactionId(r.tx_hash),
48
+ }).toCore(),
49
+ Serialization.TransactionOutput.fromCore({
50
+ address: Cardano.PaymentAddress(r.address),
51
+ value: this.__getValueFromAmount(r.amount).toCore(),
52
+ datum: r.inline_datum
53
+ ? Serialization.PlutusData.fromCbor(
54
+ HexBlob(r.inline_datum),
55
+ ).toCore()
56
+ : undefined,
57
+ datumHash: r.data_hash ? Hash32ByteBase16(r.data_hash) : undefined,
58
+ }).toCore(),
59
+ ]).toCbor();
60
+ });
61
+
62
+ return formatted;
63
+ }
64
+
65
+ private __getValueFromAmount(amount: { unit: string; quantity: string }[]) {
66
+ const lovelace = amount.find((a) => a.unit === "lovelace");
67
+ const assets = amount.filter((a) => a.unit !== "lovelace");
68
+
69
+ // Build our token map.
70
+ const tokenMap = new Map<Cardano.AssetId, bigint>();
71
+ assets.forEach((asset) => {
72
+ const matchingEntry = tokenMap.get(Cardano.AssetId(asset.unit)) || 0n;
73
+ tokenMap.set(
74
+ Cardano.AssetId(asset.unit),
75
+ BigInt(asset.quantity) + matchingEntry,
76
+ );
77
+ });
78
+
79
+ // Build our value.
80
+ const value = Serialization.Value.fromCore({
81
+ coins: BigInt(lovelace?.quantity || 0),
82
+ assets: tokenMap,
83
+ });
84
+
85
+ return value;
86
+ }
87
+ }
@@ -23,6 +23,7 @@ import {
23
23
  getCardanoUtil,
24
24
  getPeerConnect,
25
25
  } from "../utils/getLibs.js";
26
+ import { ReadOnlyApi } from "./ReadOnlyApi.class.js";
26
27
  import { WalletBalanceMap } from "./WalletBalanceMap.class.js";
27
28
  import { WalletObserverEvent } from "./WalletObserverEvent.js";
28
29
  import { WalletObserverUtils } from "./WalletObserverUtils.class.js";
@@ -227,6 +228,22 @@ export class WalletObserver<
227
228
  let attempts = 0;
228
229
  let shouldContinue = true;
229
230
 
231
+ if (selectedWallet.startsWith("addr")) {
232
+ if (!this._options.readOnlyProvider) {
233
+ throw new Error(
234
+ "You must provide a ReadOnlyProvider when connecting with a read-only address.",
235
+ );
236
+ }
237
+
238
+ this.api = new ReadOnlyApi(
239
+ selectedWallet,
240
+ selectedWallet.startsWith("addr_test") ? 0 : 1,
241
+ this._options.readOnlyProvider,
242
+ );
243
+ this.network = await this.api.getNetworkId();
244
+ return this.api;
245
+ }
246
+
230
247
  while (shouldContinue) {
231
248
  if (attempts === 10) {
232
249
  throw new Error(
@@ -296,7 +313,14 @@ export class WalletObserver<
296
313
  this.peerConnectInstance?.shutdownServer();
297
314
  }
298
315
 
299
- while (typeof extensionObject === "undefined") {
316
+ while (
317
+ typeof extensionObject === "undefined" &&
318
+ !extension.startsWith("addr")
319
+ ) {
320
+ if (this._options.debug) {
321
+ console.warn(`Could not find extension: ${extension}. Trying again...`);
322
+ }
323
+
300
324
  if (attempts === 40) {
301
325
  break;
302
326
  }
@@ -308,9 +332,11 @@ export class WalletObserver<
308
332
  attempts++;
309
333
  }
310
334
 
311
- if (!extensionObject) {
335
+ if (!extensionObject && !extension.startsWith("addr")) {
312
336
  this.dispatch(EWalletObserverEvents.CONNECT_WALLET_END);
313
- throw new Error("Wallet extension not found in the global context.");
337
+ throw new Error(
338
+ `Could not find extension (${extension}) in the global context.`,
339
+ );
314
340
  }
315
341
 
316
342
  this.activeWallet = extension;
@@ -47,7 +47,7 @@ describe("WalletObserver", async () => {
47
47
  new WalletObserver({
48
48
  connectTimeout: 10,
49
49
  }).connectWallet("flint"),
50
- ).toThrowError("Wallet extension not found in the global context.");
50
+ ).toThrowError("Could not find extension (flint) in the global context.");
51
51
  });
52
52
  });
53
53
 
@@ -1,3 +1,5 @@
1
+ export { ReadOnlyProvider } from "./ReadOnlyProvider.Abstract.class.js";
2
+ export { ReadOnlyBlockfrostProvider } from "./ReadOnlyProvider.Blockfrost.class.js";
1
3
  export { WalletAssetMap } from "./WalletAssetMap.class.js";
2
4
  export { WalletBalanceMap } from "./WalletBalanceMap.class.js";
3
5
  export { WalletObserver } from "./WalletObserver.class.js";