@meshsdk/wallet 1.6.0-alpha.11
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 +5 -0
- package/jest.config.js +5 -0
- package/package.json +36 -0
- package/src/app/index.ts +239 -0
- package/src/browser/index.ts +440 -0
- package/src/embedded/index.ts +258 -0
- package/src/index.ts +4 -0
- package/src/mesh/index.ts +413 -0
- package/src/types/index.ts +39 -0
- package/test/app.test.ts +98 -0
- package/test/browser.test.ts +21 -0
- package/test/embedded.test.ts +137 -0
- package/test/mesh.test.ts +95 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Asset,
|
|
3
|
+
AssetExtended,
|
|
4
|
+
DataSignature,
|
|
5
|
+
UTxO,
|
|
6
|
+
} from "@meshsdk/common";
|
|
7
|
+
import {
|
|
8
|
+
IFetcher,
|
|
9
|
+
IInitiator,
|
|
10
|
+
ISigner,
|
|
11
|
+
ISubmitter,
|
|
12
|
+
POLICY_ID_LENGTH,
|
|
13
|
+
resolveFingerprint,
|
|
14
|
+
toUTF8,
|
|
15
|
+
} from "@meshsdk/common";
|
|
16
|
+
import {
|
|
17
|
+
Address,
|
|
18
|
+
fromTxUnspentOutput,
|
|
19
|
+
resolvePrivateKey,
|
|
20
|
+
toTxUnspentOutput,
|
|
21
|
+
TransactionUnspentOutput,
|
|
22
|
+
} from "@meshsdk/core-cst";
|
|
23
|
+
import { Transaction } from "@meshsdk/transaction";
|
|
24
|
+
|
|
25
|
+
import { AppWallet } from "../app";
|
|
26
|
+
import { EmbeddedWallet } from "../embedded";
|
|
27
|
+
import { GetAddressType } from "../types";
|
|
28
|
+
|
|
29
|
+
export type CreateMeshWalletOptions = {
|
|
30
|
+
networkId: number;
|
|
31
|
+
fetcher?: IFetcher;
|
|
32
|
+
submitter?: ISubmitter;
|
|
33
|
+
key:
|
|
34
|
+
| {
|
|
35
|
+
type: "root";
|
|
36
|
+
bech32: string;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
type: "cli";
|
|
40
|
+
payment: string;
|
|
41
|
+
stake?: string;
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
type: "mnemonic";
|
|
45
|
+
words: string[];
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Mesh Wallet provides a set of APIs to interact with the blockchain. This wallet is compatible with Mesh transaction builders.
|
|
51
|
+
*
|
|
52
|
+
* It is a single address wallet, a wrapper around the AppWallet class.
|
|
53
|
+
*
|
|
54
|
+
* ```javascript
|
|
55
|
+
* import { MeshWallet, BlockfrostProvider } from '@meshsdksdk/core';
|
|
56
|
+
*
|
|
57
|
+
* const blockchainProvider = new BlockfrostProvider('<BLOCKFROST_API_KEY>');
|
|
58
|
+
*
|
|
59
|
+
* const wallet = new MeshWallet({
|
|
60
|
+
* networkId: 0,
|
|
61
|
+
* fetcher: blockchainProvider,
|
|
62
|
+
* submitter: blockchainProvider,
|
|
63
|
+
* key: {
|
|
64
|
+
* type: 'mnemonic',
|
|
65
|
+
* words: ["solution","solution","solution","solution","solution",","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution"],
|
|
66
|
+
* },
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export class MeshWallet implements IInitiator, ISigner, ISubmitter {
|
|
71
|
+
private readonly _wallet: AppWallet;
|
|
72
|
+
|
|
73
|
+
constructor(options: CreateMeshWalletOptions) {
|
|
74
|
+
switch (options.key.type) {
|
|
75
|
+
case "root":
|
|
76
|
+
this._wallet = new AppWallet({
|
|
77
|
+
networkId: options.networkId,
|
|
78
|
+
fetcher: options.fetcher,
|
|
79
|
+
submitter: options.submitter,
|
|
80
|
+
key: {
|
|
81
|
+
type: "root",
|
|
82
|
+
bech32: options.key.bech32,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
break;
|
|
86
|
+
case "cli":
|
|
87
|
+
this._wallet = new AppWallet({
|
|
88
|
+
networkId: options.networkId,
|
|
89
|
+
fetcher: options.fetcher,
|
|
90
|
+
submitter: options.submitter,
|
|
91
|
+
key: {
|
|
92
|
+
type: "cli",
|
|
93
|
+
payment: options.key.payment,
|
|
94
|
+
stake: options.key.stake,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
break;
|
|
98
|
+
case "mnemonic":
|
|
99
|
+
this._wallet = new AppWallet({
|
|
100
|
+
networkId: options.networkId,
|
|
101
|
+
fetcher: options.fetcher,
|
|
102
|
+
submitter: options.submitter,
|
|
103
|
+
key: {
|
|
104
|
+
type: "mnemonic",
|
|
105
|
+
words: options.key.words,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Returns a list of assets in the wallet. This API will return every assets in the wallet. Each asset is an object with the following properties:
|
|
114
|
+
* - A unit is provided to display asset's name on the user interface.
|
|
115
|
+
* - A quantity is provided to display asset's quantity on the user interface.
|
|
116
|
+
*
|
|
117
|
+
* @returns a list of assets and their quantities
|
|
118
|
+
*/
|
|
119
|
+
async getBalance(): Promise<Asset[]> {
|
|
120
|
+
const utxos = await this.getUnspentOutputs();
|
|
121
|
+
|
|
122
|
+
const assets = new Map<string, number>();
|
|
123
|
+
utxos.map((utxo) => {
|
|
124
|
+
const _utxo = fromTxUnspentOutput(utxo);
|
|
125
|
+
_utxo.output.amount.map((asset) => {
|
|
126
|
+
const assetId = asset.unit;
|
|
127
|
+
const amount = Number(asset.quantity);
|
|
128
|
+
if (assets.has(assetId)) {
|
|
129
|
+
const quantity = assets.get(assetId)!;
|
|
130
|
+
assets.set(assetId, quantity + amount);
|
|
131
|
+
} else {
|
|
132
|
+
assets.set(assetId, amount);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const arrayAssets: Asset[] = Array.from(assets, ([unit, quantity]) => ({
|
|
138
|
+
unit,
|
|
139
|
+
quantity: quantity.toString(),
|
|
140
|
+
}));
|
|
141
|
+
|
|
142
|
+
return arrayAssets;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Returns an address owned by the wallet that should be used as a change address to return leftover assets during transaction creation back to the connected wallet.
|
|
147
|
+
*
|
|
148
|
+
* @returns an address
|
|
149
|
+
*/
|
|
150
|
+
getChangeAddress(): string {
|
|
151
|
+
return this._wallet.getPaymentAddress();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* This function shall return a list of one or more UTXOs (unspent transaction outputs) controlled by the wallet that are required to reach AT LEAST the combined ADA value target specified in amount AND the best suitable to be used as collateral inputs for transactions with plutus script inputs (pure ADA-only UTXOs).
|
|
156
|
+
*
|
|
157
|
+
* If this cannot be attained, an error message with an explanation of the blocking problem shall be returned. NOTE: wallets are free to return UTXOs that add up to a greater total ADA value than requested in the amount parameter, but wallets must never return any result where UTXOs would sum up to a smaller total ADA value, instead in a case like that an error message must be returned.
|
|
158
|
+
*
|
|
159
|
+
* @returns a list of UTXOs
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
async getCollateral(
|
|
163
|
+
addressType: GetAddressType = "payment",
|
|
164
|
+
): Promise<UTxO[]> {
|
|
165
|
+
const utxos = await this._wallet.getCollateralUnspentOutput(0, addressType);
|
|
166
|
+
return utxos.map((utxo, i) => {
|
|
167
|
+
return fromTxUnspentOutput(utxo);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Returns the network ID of the currently connected account. 0 is testnet and 1 is mainnet but other networks can possibly be returned by wallets. Those other network ID values are not governed by CIP-30. This result will stay the same unless the connected account has changed.
|
|
173
|
+
*
|
|
174
|
+
* @returns network ID
|
|
175
|
+
*/
|
|
176
|
+
getNetworkId(): number {
|
|
177
|
+
return this._wallet.getNetworkId();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Returns a list of reward addresses owned by the wallet. A reward address is a stake address that is used to receive rewards from staking, generally starts from `stake` prefix.
|
|
182
|
+
*
|
|
183
|
+
* @returns a list of reward addresses
|
|
184
|
+
*/
|
|
185
|
+
getRewardAddresses(): string[] {
|
|
186
|
+
return [this._wallet.getRewardAddress()];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Returns a list of unused addresses controlled by the wallet.
|
|
191
|
+
*
|
|
192
|
+
* @returns a list of unused addresses
|
|
193
|
+
*/
|
|
194
|
+
getUnusedAddresses(): string[] {
|
|
195
|
+
return [this.getChangeAddress()];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Returns a list of used addresses controlled by the wallet.
|
|
200
|
+
*
|
|
201
|
+
* @returns a list of used addresses
|
|
202
|
+
*/
|
|
203
|
+
getUsedAddresses(): string[] {
|
|
204
|
+
return [this.getChangeAddress()];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Get a list of UTXOs to be used as collateral inputs for transactions with plutus script inputs.
|
|
209
|
+
*
|
|
210
|
+
* This is used in transaction building.
|
|
211
|
+
*
|
|
212
|
+
* @returns a list of UTXOs
|
|
213
|
+
*/
|
|
214
|
+
async getUsedCollateral(): Promise<TransactionUnspentOutput[]> {
|
|
215
|
+
const collateralUtxo = await this.getCollateral();
|
|
216
|
+
|
|
217
|
+
const unspentOutput = collateralUtxo.map((utxo) => {
|
|
218
|
+
return toTxUnspentOutput(utxo);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
return unspentOutput;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get a list of UTXOs to be used for transaction building.
|
|
226
|
+
*
|
|
227
|
+
* This is used in transaction building.
|
|
228
|
+
*
|
|
229
|
+
* @returns a list of UTXOs
|
|
230
|
+
*/
|
|
231
|
+
async getUsedUTxOs(
|
|
232
|
+
addressType?: GetAddressType,
|
|
233
|
+
): Promise<TransactionUnspentOutput[]> {
|
|
234
|
+
return await this.getUnspentOutputs(addressType);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Return a list of all UTXOs (unspent transaction outputs) controlled by the wallet.
|
|
239
|
+
*
|
|
240
|
+
* @returns a list of UTXOs
|
|
241
|
+
*/
|
|
242
|
+
async getUtxos(addressType?: GetAddressType): Promise<UTxO[]> {
|
|
243
|
+
const utxos = await this.getUsedUTxOs(addressType);
|
|
244
|
+
return utxos.map((c) => fromTxUnspentOutput(c));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* This endpoint utilizes the [CIP-8 - Message Signing](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030) to sign arbitrary data, to verify the data was signed by the owner of the private key.
|
|
249
|
+
*
|
|
250
|
+
* Here, we get the first wallet's address with wallet.getUsedAddresses(), alternativelly you can use reward addresses (getRewardAddresses()) too. It's really up to you as the developer which address you want to use in your application.
|
|
251
|
+
*
|
|
252
|
+
* @param address
|
|
253
|
+
* @param payload
|
|
254
|
+
* @returns a signature
|
|
255
|
+
*/
|
|
256
|
+
signData(payload: string): DataSignature {
|
|
257
|
+
return this._wallet.signData(this.getChangeAddress(), payload);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Requests user to sign the provided transaction (tx). The wallet should ask the user for permission, and if given, try to sign the supplied body and return a signed transaction. partialSign should be true if the transaction provided requires multiple signatures.
|
|
262
|
+
*
|
|
263
|
+
* @param unsignedTx
|
|
264
|
+
* @param partialSign
|
|
265
|
+
* @returns a signed transaction in CBOR
|
|
266
|
+
*/
|
|
267
|
+
signTx(unsignedTx: string, partialSign = false): string {
|
|
268
|
+
return this._wallet.signTx(unsignedTx, partialSign);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Experimental feature - sign multiple transactions at once.
|
|
273
|
+
*
|
|
274
|
+
* @param unsignedTxs - array of unsigned transactions in CborHex string
|
|
275
|
+
* @param partialSign - if the transactions are signed partially
|
|
276
|
+
* @returns array of signed transactions CborHex string
|
|
277
|
+
*/
|
|
278
|
+
signTxs(unsignedTxs: string[], partialSign = false): string[] {
|
|
279
|
+
const signedTxs: string[] = [];
|
|
280
|
+
|
|
281
|
+
for (const unsignedTx of unsignedTxs) {
|
|
282
|
+
const signedTx = this.signTx(unsignedTx, partialSign);
|
|
283
|
+
signedTxs.push(signedTx);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return signedTxs;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Submits the signed transaction to the blockchain network.
|
|
291
|
+
*
|
|
292
|
+
* As wallets should already have this ability to submit transaction, we allow dApps to request that a transaction be sent through it. If the wallet accepts the transaction and tries to send it, it shall return the transaction ID for the dApp to track. The wallet can return error messages or failure if there was an error in sending it.
|
|
293
|
+
*
|
|
294
|
+
* @param tx
|
|
295
|
+
* @returns a transaction hash
|
|
296
|
+
*/
|
|
297
|
+
async submitTx(tx: string): Promise<string> {
|
|
298
|
+
return await this._wallet.submitTx(tx);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Get a used address of type Address from the wallet.
|
|
303
|
+
*
|
|
304
|
+
* This is used in transaction building.
|
|
305
|
+
*
|
|
306
|
+
* @returns an Address object
|
|
307
|
+
*/
|
|
308
|
+
getUsedAddress(addressType?: GetAddressType): Address {
|
|
309
|
+
return this._wallet.getUsedAddress(0, 0, addressType);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Get a list of UTXOs to be used for transaction building.
|
|
314
|
+
*
|
|
315
|
+
* This is used in transaction building.
|
|
316
|
+
*
|
|
317
|
+
* @returns a list of UTXOs
|
|
318
|
+
*/
|
|
319
|
+
async getUnspentOutputs(
|
|
320
|
+
addressType?: GetAddressType,
|
|
321
|
+
): Promise<TransactionUnspentOutput[]> {
|
|
322
|
+
return await this._wallet.getUnspentOutputs(0, addressType);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* A helper function to get the assets in the wallet.
|
|
327
|
+
*
|
|
328
|
+
* @returns a list of assets
|
|
329
|
+
*/
|
|
330
|
+
async getAssets(): Promise<AssetExtended[]> {
|
|
331
|
+
const balance = await this.getBalance();
|
|
332
|
+
return balance
|
|
333
|
+
.filter((v) => v.unit !== "lovelace")
|
|
334
|
+
.map((v) => {
|
|
335
|
+
const policyId = v.unit.slice(0, POLICY_ID_LENGTH);
|
|
336
|
+
const assetName = v.unit.slice(POLICY_ID_LENGTH);
|
|
337
|
+
const fingerprint = resolveFingerprint(policyId, assetName);
|
|
338
|
+
|
|
339
|
+
return {
|
|
340
|
+
unit: v.unit,
|
|
341
|
+
policyId,
|
|
342
|
+
assetName: toUTF8(assetName),
|
|
343
|
+
fingerprint,
|
|
344
|
+
quantity: v.quantity,
|
|
345
|
+
};
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* A helper function to get the lovelace balance in the wallet.
|
|
351
|
+
*
|
|
352
|
+
* @returns lovelace balance
|
|
353
|
+
*/
|
|
354
|
+
async getLovelace(): Promise<string> {
|
|
355
|
+
const balance = await this.getBalance();
|
|
356
|
+
const nativeAsset = balance.find((v) => v.unit === "lovelace");
|
|
357
|
+
|
|
358
|
+
return nativeAsset !== undefined ? nativeAsset.quantity : "0";
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* A helper function to get the assets of a specific policy ID in the wallet.
|
|
363
|
+
*
|
|
364
|
+
* @param policyId
|
|
365
|
+
* @returns a list of assets
|
|
366
|
+
*/
|
|
367
|
+
async getPolicyIdAssets(policyId: string): Promise<AssetExtended[]> {
|
|
368
|
+
const assets = await this.getAssets();
|
|
369
|
+
return assets.filter((v) => v.policyId === policyId);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* A helper function to get the policy IDs of all the assets in the wallet.
|
|
374
|
+
*
|
|
375
|
+
* @returns a list of policy IDs
|
|
376
|
+
*/
|
|
377
|
+
async getPolicyIds(): Promise<string[]> {
|
|
378
|
+
const balance = await this.getBalance();
|
|
379
|
+
return Array.from(
|
|
380
|
+
new Set(balance.map((v) => v.unit.slice(0, POLICY_ID_LENGTH))),
|
|
381
|
+
).filter((p) => p !== "lovelace");
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* A helper function to create a collateral input for a transaction.
|
|
386
|
+
*
|
|
387
|
+
* @returns a transaction hash
|
|
388
|
+
*/
|
|
389
|
+
async createCollateral(): Promise<string> {
|
|
390
|
+
const tx = new Transaction({ initiator: this });
|
|
391
|
+
tx.sendLovelace(this.getChangeAddress(), "5000000");
|
|
392
|
+
const unsignedTx = await tx.build();
|
|
393
|
+
const signedTx = await this.signTx(unsignedTx);
|
|
394
|
+
const txHash = await this.submitTx(signedTx);
|
|
395
|
+
return txHash;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Generate mnemonic or private key
|
|
400
|
+
*
|
|
401
|
+
* @param privateKey return private key if true
|
|
402
|
+
* @returns a transaction hash
|
|
403
|
+
*/
|
|
404
|
+
static brew(privateKey = false, strength = 256): string[] | string {
|
|
405
|
+
const mnemonic = EmbeddedWallet.generateMnemonic(strength);
|
|
406
|
+
|
|
407
|
+
if (privateKey) {
|
|
408
|
+
return resolvePrivateKey(mnemonic);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return mnemonic;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { DataSignature } from "@meshsdk/common";
|
|
2
|
+
|
|
3
|
+
export type Cardano = {
|
|
4
|
+
[key: string]: {
|
|
5
|
+
name: string;
|
|
6
|
+
icon: string;
|
|
7
|
+
apiVersion: string;
|
|
8
|
+
enable: () => Promise<WalletInstance>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type TransactionSignatureRequest = {
|
|
13
|
+
cbor: string;
|
|
14
|
+
partialSign: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type WalletInstance = {
|
|
18
|
+
experimental: ExperimentalFeatures;
|
|
19
|
+
getBalance(): Promise<string>;
|
|
20
|
+
getChangeAddress(): Promise<string>;
|
|
21
|
+
getNetworkId(): Promise<number>;
|
|
22
|
+
getRewardAddresses(): Promise<string[]>;
|
|
23
|
+
getUnusedAddresses(): Promise<string[]>;
|
|
24
|
+
getUsedAddresses(): Promise<string[]>;
|
|
25
|
+
getUtxos(): Promise<string[] | undefined>;
|
|
26
|
+
signData(address: string, payload: string): Promise<DataSignature>;
|
|
27
|
+
signTx(tx: string, partialSign: boolean): Promise<string>;
|
|
28
|
+
signTxs?(txs: TransactionSignatureRequest[]): Promise<string[]>; // Overloading interface as currently no standard
|
|
29
|
+
signTxs?(txs: string[], partialSign: boolean): Promise<string[]>; // Overloading interface as currently no standard
|
|
30
|
+
submitTx(tx: string): Promise<string>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type ExperimentalFeatures = {
|
|
34
|
+
getCollateral(): Promise<string[] | undefined>;
|
|
35
|
+
signTxs?(txs: TransactionSignatureRequest[]): Promise<string[]>; // Overloading interface as currently no standard
|
|
36
|
+
signTxs?(txs: string[], partialSign: boolean): Promise<string[]>; // Overloading interface as currently no standard
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type GetAddressType = "enterprise" | "payment";
|
package/test/app.test.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { AppWallet } from "@meshsdk/wallet";
|
|
2
|
+
|
|
3
|
+
describe("AppWallet", () => {
|
|
4
|
+
const wallet = new AppWallet({
|
|
5
|
+
networkId: 0,
|
|
6
|
+
key: {
|
|
7
|
+
type: "mnemonic",
|
|
8
|
+
words: "solution,".repeat(24).split(",").slice(0, 24),
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("brew", () => {
|
|
13
|
+
const mnemonic = AppWallet.brew();
|
|
14
|
+
expect(mnemonic.length).toEqual(24);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("private keys", () => {
|
|
18
|
+
const wallet = new AppWallet({
|
|
19
|
+
networkId: 0,
|
|
20
|
+
key: {
|
|
21
|
+
type: "root",
|
|
22
|
+
bech32:
|
|
23
|
+
"xprv1cqa46gk29plgkg98upclnjv5t425fcpl4rgf9mq2txdxuga7jfq5shk7np6l55nj00sl3m4syzna3uwgrwppdm0azgy9d8zahyf32s62klfyhe0ayyxkc7x92nv4s77fa0v25tufk9tnv7x6dgexe9kdz5gpeqgu",
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const paymentAddress = wallet.getPaymentAddress();
|
|
28
|
+
expect(paymentAddress).toEqual(
|
|
29
|
+
"addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9",
|
|
30
|
+
);
|
|
31
|
+
const enterpriseAddress = wallet.getEnterpriseAddress();
|
|
32
|
+
expect(enterpriseAddress).toEqual(
|
|
33
|
+
"addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr",
|
|
34
|
+
);
|
|
35
|
+
const rewardAddress = wallet.getRewardAddress();
|
|
36
|
+
expect(rewardAddress).toEqual(
|
|
37
|
+
"stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n",
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("cli keys", () => {
|
|
42
|
+
const wallet = new AppWallet({
|
|
43
|
+
networkId: 0,
|
|
44
|
+
key: {
|
|
45
|
+
type: "cli",
|
|
46
|
+
payment:
|
|
47
|
+
"5820f083e5878c6f980c53d30b9cc2baadd780307b08acec9e0792892e013bbe9241",
|
|
48
|
+
stake:
|
|
49
|
+
"5820b810d6398db44f380a9ab279f63950c4b95432f44fafb5a6f026afe23bbe9241",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const paymentAddress = wallet.getPaymentAddress();
|
|
54
|
+
expect(paymentAddress).toEqual(
|
|
55
|
+
"addr_test1qqdy60gf798xrl20wwvapvsxj3kr8yz8ac6zfmgwg6c5g9p3x07mt562mneg8jxgj03p2uvmhyfyvktjn259mws8e6wq3cdn8p",
|
|
56
|
+
);
|
|
57
|
+
const enterpriseAddress = wallet.getEnterpriseAddress();
|
|
58
|
+
expect(enterpriseAddress).toEqual(
|
|
59
|
+
"addr_test1vqdy60gf798xrl20wwvapvsxj3kr8yz8ac6zfmgwg6c5g9qh602xh",
|
|
60
|
+
);
|
|
61
|
+
const rewardAddress = wallet.getRewardAddress();
|
|
62
|
+
expect(rewardAddress).toEqual(
|
|
63
|
+
"stake_test1uqcn8ld46d9deu5reryf8cs4wxdmjyjxt9ef42zahgrua8qctnd74",
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("correct payment address", () => {
|
|
68
|
+
const paymentAddress = wallet.getPaymentAddress();
|
|
69
|
+
expect(paymentAddress).toEqual(
|
|
70
|
+
"addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9",
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("correct enterprise address", () => {
|
|
75
|
+
const enterpriseAddress = wallet.getEnterpriseAddress();
|
|
76
|
+
expect(enterpriseAddress).toEqual(
|
|
77
|
+
"addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr",
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("correct reward address", () => {
|
|
82
|
+
const rewardAddress = wallet.getRewardAddress();
|
|
83
|
+
expect(rewardAddress).toEqual(
|
|
84
|
+
"stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n",
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("correct used addresses", () => {
|
|
89
|
+
const paymentAddress = wallet.getUsedAddress();
|
|
90
|
+
expect(paymentAddress.toBech32()).toEqual(
|
|
91
|
+
"addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9",
|
|
92
|
+
);
|
|
93
|
+
const enterpriseAddress = wallet.getUsedAddress(0, 0, "enterprise");
|
|
94
|
+
expect(enterpriseAddress.toBech32()).toEqual(
|
|
95
|
+
"addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr",
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CardanoSDKUtil, Serialization } from "@meshsdk/core-cst";
|
|
2
|
+
|
|
3
|
+
import { WalletStaticMethods } from "../src";
|
|
4
|
+
|
|
5
|
+
describe("BroswerWallet", () => {
|
|
6
|
+
it("signTx: addWitnessSet", () => {
|
|
7
|
+
const unsignedTx =
|
|
8
|
+
"84a4008282582023925df9067578d15e766d5e7aacf3f1af5b0eb5a90abd9c9281e4881338317e01825820c9b837816abbdcd28ba3905752b24054ca0d8f5b510d15567041e96bb18b2a29000182825839005867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e61a0016e360825839001e4eb194e3335a0dcc4f5c5d009318167c583bb3b0879d9f718cd9e0d63a93470bd4d8bb986c02ff8a6043796b91cc397ceb29058f5c9ac01a4387095e021a0002a98d0d83825820423351f26b28a089171fb9a6cfb824de99524972c59958533beba877af74503c01825820d06a742f2b8fe2bad4c38e2db9e9dfe924235d2d0b894d207b251f9cfc93e85103825820ec0c2e70b898cf531b03c9db937602e98c45378d9fa8e8a5b5a91ec5c1d7540d05a0f5f6";
|
|
9
|
+
const witness =
|
|
10
|
+
"a10081825820cb845bb836d4baf4edffb9f76198072cbc70f0d8bb5402644ffd4db17e65259f58403c82976d080de380506a8fd78afc5e8a0ab4367916c943f368b8541e8aca8cbe4d98e4106a7da065918a676849c00201aed154cda38348220960aba80bb5190a";
|
|
11
|
+
const cWitness = Serialization.TransactionWitnessSet.fromCbor(
|
|
12
|
+
CardanoSDKUtil.HexBlob(witness),
|
|
13
|
+
);
|
|
14
|
+
const signedTx = WalletStaticMethods.addWitnessSets(unsignedTx, [
|
|
15
|
+
...cWitness.vkeys()?.values()!,
|
|
16
|
+
]);
|
|
17
|
+
expect(signedTx).toEqual(
|
|
18
|
+
"84a4008282582023925df9067578d15e766d5e7aacf3f1af5b0eb5a90abd9c9281e4881338317e01825820c9b837816abbdcd28ba3905752b24054ca0d8f5b510d15567041e96bb18b2a29000182825839005867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e61a0016e360825839001e4eb194e3335a0dcc4f5c5d009318167c583bb3b0879d9f718cd9e0d63a93470bd4d8bb986c02ff8a6043796b91cc397ceb29058f5c9ac01a4387095e021a0002a98d0d83825820423351f26b28a089171fb9a6cfb824de99524972c59958533beba877af74503c01825820d06a742f2b8fe2bad4c38e2db9e9dfe924235d2d0b894d207b251f9cfc93e85103825820ec0c2e70b898cf531b03c9db937602e98c45378d9fa8e8a5b5a91ec5c1d7540d05a10081825820cb845bb836d4baf4edffb9f76198072cbc70f0d8bb5402644ffd4db17e65259f58403c82976d080de380506a8fd78afc5e8a0ab4367916c943f368b8541e8aca8cbe4d98e4106a7da065918a676849c00201aed154cda38348220960aba80bb5190af5f6",
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
});
|