Skip to content

Commit 516dc9d

Browse files
committed
PLT-6951 - Add method to get available wallets
1 parent 8000365 commit 516dc9d

File tree

5 files changed

+99
-46
lines changed

5 files changed

+99
-46
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
],
1717
"license": "Apache-2.0",
1818
"scripts": {
19-
"build": "tsc --build && rollup --config rollup/runtime-esm.config.mjs",
19+
"build": "tsc --build && rollup --config rollup/runtime-esm.config.mjs && rollup --config rollup/wallet-esm.config.mjs",
2020
"clean": "npm run clean --workspaces && shx rm -rf dist",
2121
"test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest",
2222
"docs": "typedoc ."

packages/wallet/Readme.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
This package provides functionality to work with a CIP30 wallet.
44

55
It has the following modules:
6-
* api: provides an abstract interface to work with a wallet.
7-
* browser: provides a browser implementation of the api using the [CIP30 specification](https://cips.cardano.org/cips/cip30/).
8-
* nodejs: provides a server implementation of the api using [Lucid](https://github.com/spacebudz/lucid) (NOTE: the underlying library might be replaced in the future)
6+
7+
- api: provides an abstract interface to work with a wallet.
8+
- browser: provides a browser implementation of the api using the [CIP30 specification](https://cips.cardano.org/cips/cip30/).
9+
- nodejs: provides a server implementation of the api using [Lucid](https://github.com/spacebudz/lucid) (NOTE: the underlying library might be replaced in the future)

packages/wallet/src/browser/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
unTxOutRef,
2222
} from "@marlowe.io/runtime-core";
2323

24+
export type SupportedWallets = "nami" | "eternl";
25+
2426
export const getExtensionInstance: (
2527
extensionName: string
2628
) => T.Task<WalletAPI> = (extensionName) =>
@@ -39,6 +41,21 @@ export const getExtensionInstance: (
3941
}))
4042
);
4143

44+
/**
45+
* Get a list of the available wallets installed in the browser
46+
*/
47+
export function getAvailableWallets(): SupportedWallets[] {
48+
if ("cardano" in window) {
49+
// NOTE: it would be nice to have a Type assertion that the supportedWallets array is
50+
// the same as the SupportedWallets type union. I've tried the other way (infering the type
51+
// from the array) but the exported documentation doesn't look good
52+
const supportedWallets = ["nami", "eternl"] as SupportedWallets[];
53+
return supportedWallets.filter((wallet) => wallet in window.cardano);
54+
} else {
55+
return [];
56+
}
57+
}
58+
4259
const waitConfirmation: (
4360
extensionCIP30Instance: BroswerExtensionCIP30Api
4461
) => (txHash: string) => TE.TaskEither<Error, boolean> =

pocs/wallet-flow.html

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,96 +6,101 @@
66
<title>withdraw POC</title>
77
</head>
88
<body>
9-
<label for="runtimeUrl">URL to a Marlowe Runtime instance:</label>
10-
<input
11-
id="runtimeUrl"
12-
type="text"
13-
autocomplete="on"
14-
placeholder="http://localhost:32952"
15-
/>
16-
<br />
179
<label for="wallet">Select wallet:</label>
18-
<select id="wallet" name="wallet">
19-
<option value="nami">Nami</option>
20-
<option value="eternl">Eternl</option>
21-
</select>
10+
<select id="wallet" name="wallet"></select>
2211
<br />
2312
<input id="start-flow" type="button" value="Start flow" />
2413
<hr />
2514
<div id="console"></div>
2615

2716
<script type="module">
28-
import { Browser } from "/dist/runtime/esm/index.js";
17+
import {
18+
getExtensionInstance,
19+
getAvailableWallets,
20+
} from "/dist/wallet/esm/index.js";
2921
const consoleDiv = document.getElementById("console");
22+
const walletInput = document.getElementById("wallet");
23+
const availableWallets = getAvailableWallets();
24+
if (availableWallets.length === 0) {
25+
const option = document.createElement("option");
26+
option.value = "invalid";
27+
option.text = "No wallet available";
28+
walletInput.add(option);
29+
walletInput.disabled = true;
30+
} else {
31+
availableWallets.forEach((walletName) => {
32+
const option = document.createElement("option");
33+
option.value = walletName;
34+
option.text =
35+
walletName.charAt(0).toUpperCase() + walletName.slice(1);
36+
walletInput.add(option);
37+
});
38+
}
3039

3140
const log = (message) => {
3241
var currentContent = consoleDiv.innerHTML;
3342
consoleDiv.innerHTML = currentContent + "<\BR>" + message;
3443
};
3544

36-
console.log("Browser", Browser);
37-
3845
async function cip30Flow() {
3946
// Clear console
4047
consoleDiv.innerHTML = "";
4148

42-
const runtimeUrlInput = document.getElementById("runtimeUrl");
43-
const runtimeUrl = runtimeUrlInput.value || "http://localhost:32952";
44-
const walletInput = document.getElementById("wallet");
45-
const wallet = walletInput.value;
49+
const walletName = walletInput.value;
4650

47-
log(`<h2>Accessing ${wallet} Wallet Extension</h2>`);
48-
const runtime = await Browser.mkRuntimeLifecycle(runtimeUrl)(wallet)();
51+
log(`<h2>Accessing ${walletName} Wallet Extension</h2>`);
52+
const wallet = await getExtensionInstance(walletName)();
4953
log("");
5054
log("Reading Wallet information...");
5155
log("");
5256

53-
const cip30Network = await runtime.wallet.getCIP30Network();
57+
const cip30Network = await wallet.getCIP30Network();
5458
log(`* <b>Network</b>: ${cip30Network}`);
5559
log(
5660
"&nbsp;&nbsp;&nbsp;NOTE: The CIP30 standard can't distinguish between testnet networks (preprod/preview/etc)"
5761
);
58-
log("")
62+
log("");
5963

60-
const lovelaces = await runtime.wallet.getLovelaces();
64+
const lovelaces = await wallet.getLovelaces();
6165
log("- <b>Lovelaces</b>: " + lovelaces.right);
62-
const tokensResult = await runtime.wallet.getTokens();
63-
log("")
66+
const tokensResult = await wallet.getTokens();
67+
log("");
6468

6569
log(`- <b>Tokens</b>: (${tokensResult.right.length} tokens)`);
6670
tokensResult.right.map((token) => {
6771
const tokenName =
6872
token.assetId.assetName == ""
6973
? "lovelaces"
7074
: token.assetId.assetName;
71-
log(
72-
`&nbsp;&nbsp;&nbsp; <i>${tokenName}</i> - ${token.quantity}`
73-
);
75+
log(`&nbsp;&nbsp;&nbsp; <i>${tokenName}</i> - ${token.quantity}`);
7476
});
75-
log("")
77+
log("");
7678

77-
const changeAddress = await runtime.wallet.getChangeAddress();
79+
const changeAddress = await wallet.getChangeAddress();
7880
log("- <b>Change Address</b>: " + changeAddress);
79-
log("")
81+
log("");
8082

81-
const usedAddresses = await runtime.wallet.getUsedAddresses();
83+
const usedAddresses = await wallet.getUsedAddresses();
8284
log(`- <b>Used Addresses</b>: (${usedAddresses.length} addresses)`);
8385
usedAddresses.map((usedAddress) =>
8486
log("&nbsp;&nbsp;&nbsp; - " + usedAddress)
8587
);
86-
log("")
88+
log("");
8789

88-
const collaterals = await runtime.wallet.getCollaterals()
89-
log(`- <b>Collaterals</b>: (${collaterals.length} collaterals)`)
90-
collaterals.map(collateral=> log( '&nbsp;&nbsp;&nbsp; - '+ collateral ))
91-
log("")
90+
const collaterals = await wallet.getCollaterals();
91+
log(`- <b>Collaterals</b>: (${collaterals.length} collaterals)`);
92+
collaterals.map((collateral) =>
93+
log("&nbsp;&nbsp;&nbsp; - " + collateral)
94+
);
95+
log("");
9296

93-
const utxos = await runtime.wallet.getUTxOs()
94-
log(`- <b>UTxOs</b>: (${utxos.length} utxos)`)
95-
utxos.map(utxo=> log( '&nbsp;&nbsp;&nbsp; - '+ utxo ))
97+
const utxos = await wallet.getUTxOs();
98+
log(`- <b>UTxOs</b>: (${utxos.length} utxos)`);
99+
utxos.map((utxo) => log("&nbsp;&nbsp;&nbsp; - " + utxo));
100+
log("");
101+
log("Wallet flow done 🎉");
96102
}
97103

98-
99104
const startFlowButton = document.getElementById("start-flow");
100105
startFlowButton.addEventListener("click", cip30Flow);
101106
</script>

rollup/wallet-esm.config.mjs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { nodeResolve } from '@rollup/plugin-node-resolve';
2+
import copy from 'rollup-plugin-copy'
3+
import commonjs from '@rollup/plugin-commonjs';
4+
import outputSize from 'rollup-plugin-output-size';
5+
import { visualizer } from "rollup-plugin-visualizer";
6+
7+
const outputDir = 'dist/wallet/esm';
8+
const nodePlugin = nodeResolve(
9+
{ browser: true
10+
});
11+
12+
const copyWasm = copy({
13+
targets: [
14+
{ src: 'node_modules/lucid-cardano/esm/src/core/wasm_modules/cardano_multiplatform_lib_web/*.wasm', dest: `${outputDir}/wasm_modules/cardano_multiplatform_lib_web/` },
15+
{ src: 'node_modules/lucid-cardano/esm/src/core/wasm_modules/cardano_message_signing_web/*.wasm', dest: `${outputDir}/wasm_modules/cardano_message_signing_web/` },
16+
]})
17+
18+
export default {
19+
input: 'packages/wallet/dist/browser/index.js',
20+
output: {
21+
dir: outputDir,
22+
format: 'esm',
23+
},
24+
plugins:
25+
[ nodePlugin
26+
, commonjs()
27+
, copyWasm
28+
, outputSize()
29+
, visualizer()],
30+
}

0 commit comments

Comments
 (0)