@arkade-os/sdk 0.2.2 → 0.3.0-alpha.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 +114 -43
- package/dist/cjs/adapters/asyncStorage.js +5 -0
- package/dist/cjs/adapters/fileSystem.js +5 -0
- package/dist/cjs/adapters/indexedDB.js +5 -0
- package/dist/cjs/adapters/localStorage.js +5 -0
- package/dist/cjs/bip322/index.js +2 -2
- package/dist/cjs/identity/index.js +15 -0
- package/dist/cjs/identity/singleKey.js +20 -1
- package/dist/cjs/index.js +5 -3
- package/dist/cjs/musig2/keys.js +6 -6
- package/dist/cjs/musig2/sign.js +5 -5
- package/dist/cjs/repositories/contractRepository.js +130 -0
- package/dist/cjs/repositories/index.js +18 -0
- package/dist/cjs/repositories/walletRepository.js +136 -0
- package/dist/cjs/storage/asyncStorage.js +47 -0
- package/dist/cjs/storage/fileSystem.js +138 -0
- package/dist/cjs/storage/inMemory.js +21 -0
- package/dist/cjs/storage/indexedDB.js +97 -0
- package/dist/cjs/storage/localStorage.js +48 -0
- package/dist/cjs/tree/signingSession.js +4 -4
- package/dist/cjs/wallet/onchain.js +12 -6
- package/dist/cjs/wallet/serviceWorker/request.js +4 -14
- package/dist/cjs/wallet/serviceWorker/response.js +0 -13
- package/dist/cjs/wallet/serviceWorker/wallet.js +124 -130
- package/dist/cjs/wallet/serviceWorker/worker.js +89 -53
- package/dist/cjs/wallet/wallet.js +21 -4
- package/dist/esm/adapters/asyncStorage.js +1 -0
- package/dist/esm/adapters/fileSystem.js +1 -0
- package/dist/esm/adapters/indexedDB.js +1 -0
- package/dist/esm/adapters/localStorage.js +1 -0
- package/dist/esm/bip322/index.js +1 -1
- package/dist/esm/identity/index.js +1 -1
- package/dist/esm/identity/singleKey.js +21 -2
- package/dist/esm/index.js +4 -3
- package/dist/esm/musig2/keys.js +6 -6
- package/dist/esm/musig2/sign.js +4 -4
- package/dist/esm/repositories/contractRepository.js +126 -0
- package/dist/esm/repositories/index.js +2 -0
- package/dist/esm/repositories/walletRepository.js +132 -0
- package/dist/esm/storage/asyncStorage.js +43 -0
- package/dist/esm/storage/fileSystem.js +101 -0
- package/dist/esm/storage/inMemory.js +17 -0
- package/dist/esm/storage/indexedDB.js +93 -0
- package/dist/esm/storage/localStorage.js +44 -0
- package/dist/esm/tree/signingSession.js +1 -1
- package/dist/esm/wallet/onchain.js +12 -6
- package/dist/esm/wallet/serviceWorker/request.js +4 -14
- package/dist/esm/wallet/serviceWorker/response.js +0 -13
- package/dist/esm/wallet/serviceWorker/wallet.js +125 -131
- package/dist/esm/wallet/serviceWorker/worker.js +90 -54
- package/dist/esm/wallet/wallet.js +21 -4
- package/dist/types/adapters/asyncStorage.d.ts +2 -0
- package/dist/types/adapters/fileSystem.d.ts +2 -0
- package/dist/types/adapters/indexedDB.d.ts +2 -0
- package/dist/types/adapters/localStorage.d.ts +2 -0
- package/dist/types/identity/index.d.ts +3 -1
- package/dist/types/identity/singleKey.d.ts +12 -1
- package/dist/types/index.d.ts +4 -4
- package/dist/types/repositories/contractRepository.d.ts +20 -0
- package/dist/types/repositories/index.d.ts +2 -0
- package/dist/types/repositories/walletRepository.d.ts +38 -0
- package/dist/types/storage/asyncStorage.d.ts +9 -0
- package/dist/types/storage/fileSystem.d.ts +11 -0
- package/dist/types/storage/inMemory.d.ts +8 -0
- package/dist/types/storage/index.d.ts +6 -0
- package/dist/types/storage/indexedDB.d.ts +12 -0
- package/dist/types/storage/localStorage.d.ts +8 -0
- package/dist/types/wallet/index.d.ts +3 -0
- package/dist/types/wallet/onchain.d.ts +3 -2
- package/dist/types/wallet/serviceWorker/request.d.ts +1 -7
- package/dist/types/wallet/serviceWorker/response.d.ts +1 -8
- package/dist/types/wallet/serviceWorker/wallet.d.ts +67 -21
- package/dist/types/wallet/serviceWorker/worker.d.ts +17 -4
- package/dist/types/wallet/wallet.d.ts +4 -0
- package/package.json +38 -14
- package/dist/cjs/wallet/serviceWorker/db/vtxo/idb.js +0 -185
- package/dist/esm/wallet/serviceWorker/db/vtxo/idb.js +0 -181
- package/dist/types/wallet/serviceWorker/db/vtxo/idb.d.ts +0 -20
- package/dist/types/wallet/serviceWorker/db/vtxo/index.d.ts +0 -14
- /package/dist/cjs/{wallet/serviceWorker/db/vtxo → storage}/index.js +0 -0
- /package/dist/esm/{wallet/serviceWorker/db/vtxo → storage}/index.js +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export class LocalStorageAdapter {
|
|
2
|
+
getSafeLocalStorage() {
|
|
3
|
+
try {
|
|
4
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
// Test access to ensure localStorage is actually available
|
|
8
|
+
window.localStorage.length;
|
|
9
|
+
return window.localStorage;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
// localStorage may throw in some environments (e.g., private browsing, disabled storage)
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async getItem(key) {
|
|
17
|
+
const localStorage = this.getSafeLocalStorage();
|
|
18
|
+
if (!localStorage) {
|
|
19
|
+
throw new Error("localStorage is not available in this environment");
|
|
20
|
+
}
|
|
21
|
+
return localStorage.getItem(key);
|
|
22
|
+
}
|
|
23
|
+
async setItem(key, value) {
|
|
24
|
+
const localStorage = this.getSafeLocalStorage();
|
|
25
|
+
if (!localStorage) {
|
|
26
|
+
throw new Error("localStorage is not available in this environment");
|
|
27
|
+
}
|
|
28
|
+
localStorage.setItem(key, value);
|
|
29
|
+
}
|
|
30
|
+
async removeItem(key) {
|
|
31
|
+
const localStorage = this.getSafeLocalStorage();
|
|
32
|
+
if (!localStorage) {
|
|
33
|
+
throw new Error("localStorage is not available in this environment");
|
|
34
|
+
}
|
|
35
|
+
localStorage.removeItem(key);
|
|
36
|
+
}
|
|
37
|
+
async clear() {
|
|
38
|
+
const localStorage = this.getSafeLocalStorage();
|
|
39
|
+
if (!localStorage) {
|
|
40
|
+
throw new Error("localStorage is not available in this environment");
|
|
41
|
+
}
|
|
42
|
+
localStorage.clear();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as musig2 from '../musig2/index.js';
|
|
2
2
|
import { Script, SigHash } from "@scure/btc-signer";
|
|
3
3
|
import { hex } from "@scure/base";
|
|
4
|
-
import { schnorr, secp256k1 } from "@noble/curves/secp256k1";
|
|
4
|
+
import { schnorr, secp256k1 } from "@noble/curves/secp256k1.js";
|
|
5
5
|
import { randomPrivateKeyBytes, sha256x2 } from "@scure/btc-signer/utils";
|
|
6
6
|
import { CosignerPublicKey, getArkPsbtFields } from '../utils/unknownFields.js';
|
|
7
7
|
export const ErrMissingVtxoGraph = new Error("missing vtxo graph");
|
|
@@ -13,7 +13,7 @@ import { TxWeightEstimator } from '../utils/txSizeEstimator.js';
|
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```typescript
|
|
16
|
-
* const wallet =
|
|
16
|
+
* const wallet = await OnchainWallet.create(identity, 'mainnet');
|
|
17
17
|
* const balance = await wallet.getBalance();
|
|
18
18
|
* const txid = await wallet.send({
|
|
19
19
|
* address: 'bc1...',
|
|
@@ -22,15 +22,21 @@ import { TxWeightEstimator } from '../utils/txSizeEstimator.js';
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export class OnchainWallet {
|
|
25
|
-
constructor(identity, network, provider) {
|
|
25
|
+
constructor(identity, network, onchainP2TR, provider) {
|
|
26
26
|
this.identity = identity;
|
|
27
|
-
|
|
27
|
+
this.network = network;
|
|
28
|
+
this.onchainP2TR = onchainP2TR;
|
|
29
|
+
this.provider = provider;
|
|
30
|
+
}
|
|
31
|
+
static async create(identity, networkName, provider) {
|
|
32
|
+
const pubkey = await identity.xOnlyPublicKey();
|
|
28
33
|
if (!pubkey) {
|
|
29
34
|
throw new Error("Invalid configured public key");
|
|
30
35
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
const network = getNetwork(networkName);
|
|
37
|
+
const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
|
|
38
|
+
const onchainP2TR = p2tr(pubkey, undefined, network);
|
|
39
|
+
return new OnchainWallet(identity, network, onchainP2TR, onchainProvider);
|
|
34
40
|
}
|
|
35
41
|
get address() {
|
|
36
42
|
return this.onchainP2TR.address || "";
|
|
@@ -9,13 +9,13 @@ export var Request;
|
|
|
9
9
|
Request.isBase = isBase;
|
|
10
10
|
function isInitWallet(message) {
|
|
11
11
|
return (message.type === "INIT_WALLET" &&
|
|
12
|
-
"privateKey" in message &&
|
|
13
|
-
typeof message.privateKey === "string" &&
|
|
14
12
|
"arkServerUrl" in message &&
|
|
15
13
|
typeof message.arkServerUrl === "string" &&
|
|
14
|
+
"privateKey" in message &&
|
|
15
|
+
typeof message.privateKey === "string" &&
|
|
16
16
|
("arkServerPublicKey" in message
|
|
17
|
-
?
|
|
18
|
-
message.arkServerPublicKey ===
|
|
17
|
+
? message.arkServerPublicKey === undefined ||
|
|
18
|
+
typeof message.arkServerPublicKey === "string"
|
|
19
19
|
: true));
|
|
20
20
|
}
|
|
21
21
|
Request.isInitWallet = isInitWallet;
|
|
@@ -66,14 +66,4 @@ export var Request;
|
|
|
66
66
|
return message.type === "GET_STATUS";
|
|
67
67
|
}
|
|
68
68
|
Request.isGetStatus = isGetStatus;
|
|
69
|
-
function isSign(message) {
|
|
70
|
-
return (message.type === "SIGN" &&
|
|
71
|
-
"tx" in message &&
|
|
72
|
-
typeof message.tx === "string" &&
|
|
73
|
-
("inputIndexes" in message && message.inputIndexes != undefined
|
|
74
|
-
? Array.isArray(message.inputIndexes) &&
|
|
75
|
-
message.inputIndexes.every((index) => typeof index === "number")
|
|
76
|
-
: true));
|
|
77
|
-
}
|
|
78
|
-
Request.isSign = isSign;
|
|
79
69
|
})(Request || (Request = {}));
|
|
@@ -172,17 +172,4 @@ export var Response;
|
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
Response.clearResponse = clearResponse;
|
|
175
|
-
function signSuccess(id, tx) {
|
|
176
|
-
return {
|
|
177
|
-
type: "SIGN_SUCCESS",
|
|
178
|
-
success: true,
|
|
179
|
-
tx,
|
|
180
|
-
id,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
Response.signSuccess = signSuccess;
|
|
184
|
-
function isSignSuccess(response) {
|
|
185
|
-
return response.type === "SIGN_SUCCESS" && response.success === true;
|
|
186
|
-
}
|
|
187
|
-
Response.isSignSuccess = isSignSuccess;
|
|
188
175
|
})(Response || (Response = {}));
|
|
@@ -1,92 +1,90 @@
|
|
|
1
1
|
import { Response } from './response.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { hex } from "@scure/base";
|
|
3
|
+
import { IndexedDBStorageAdapter } from '../../storage/indexedDB.js';
|
|
4
|
+
import { WalletRepositoryImpl } from '../../repositories/walletRepository.js';
|
|
5
|
+
import { ContractRepositoryImpl } from '../../repositories/contractRepository.js';
|
|
6
|
+
import { setupServiceWorker } from './utils.js';
|
|
7
|
+
const isPrivateKeyIdentity = (identity) => {
|
|
8
|
+
return (identity.toHex !== undefined &&
|
|
9
|
+
typeof identity.toHex === "function" &&
|
|
10
|
+
typeof identity.toHex() === "string" &&
|
|
11
|
+
identity.toHex().length > 0);
|
|
12
|
+
};
|
|
6
13
|
class UnexpectedResponseError extends Error {
|
|
7
14
|
constructor(response) {
|
|
8
15
|
super(`Unexpected response type. Got: ${JSON.stringify(response, null, 2)}`);
|
|
9
16
|
this.name = "UnexpectedResponseError";
|
|
10
17
|
}
|
|
11
18
|
}
|
|
12
|
-
/**
|
|
13
|
-
* Service Worker-based wallet implementation for browser environments.
|
|
14
|
-
*
|
|
15
|
-
* This wallet uses a service worker as a backend to handle wallet logic,
|
|
16
|
-
* providing secure key storage and transaction signing in web applications.
|
|
17
|
-
* The service worker runs in a separate thread and can persist data between
|
|
18
|
-
* browser sessions.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* // Create and initialize the service worker wallet
|
|
23
|
-
* const serviceWorker = await setupServiceWorker("/service-worker.js");
|
|
24
|
-
* const wallet = new ServiceWorkerWallet(serviceWorker);
|
|
25
|
-
* await wallet.init({
|
|
26
|
-
* privateKey: 'your_private_key_hex',
|
|
27
|
-
* arkServerUrl: 'https://ark.example.com'
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* // Use like any other wallet
|
|
31
|
-
* const address = await wallet.getAddress();
|
|
32
|
-
* const balance = await wallet.getBalance();
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
19
|
export class ServiceWorkerWallet {
|
|
36
|
-
constructor(serviceWorker) {
|
|
20
|
+
constructor(serviceWorker, identity, walletRepository, contractRepository) {
|
|
37
21
|
this.serviceWorker = serviceWorker;
|
|
22
|
+
this.identity = identity;
|
|
23
|
+
this.walletRepository = walletRepository;
|
|
24
|
+
this.contractRepository = contractRepository;
|
|
38
25
|
}
|
|
39
|
-
async
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
throw new UnexpectedResponseError(response);
|
|
52
|
-
}
|
|
53
|
-
async init(config, failIfInitialized = false) {
|
|
54
|
-
// Check if wallet is already initialized
|
|
55
|
-
const statusMessage = {
|
|
56
|
-
type: "GET_STATUS",
|
|
57
|
-
id: getRandomId(),
|
|
58
|
-
};
|
|
59
|
-
const response = await this.sendMessage(statusMessage);
|
|
60
|
-
if (Response.isWalletStatus(response) &&
|
|
61
|
-
response.status.walletInitialized) {
|
|
62
|
-
if (failIfInitialized) {
|
|
63
|
-
throw new Error("Wallet already initialized");
|
|
64
|
-
}
|
|
65
|
-
this.cachedXOnlyPublicKey = response.status.xOnlyPublicKey;
|
|
66
|
-
return;
|
|
26
|
+
static async create(options) {
|
|
27
|
+
// Default to IndexedDB for service worker context
|
|
28
|
+
const storage = options.storage || new IndexedDBStorageAdapter("wallet-db");
|
|
29
|
+
// Create repositories
|
|
30
|
+
const walletRepo = new WalletRepositoryImpl(storage);
|
|
31
|
+
const contractRepo = new ContractRepositoryImpl(storage);
|
|
32
|
+
// Extract identity and check if it can expose private key
|
|
33
|
+
const identity = isPrivateKeyIdentity(options.identity)
|
|
34
|
+
? options.identity
|
|
35
|
+
: null;
|
|
36
|
+
if (!identity) {
|
|
37
|
+
throw new Error("ServiceWorkerWallet.create() requires a Identity that can expose its private key");
|
|
67
38
|
}
|
|
68
|
-
//
|
|
69
|
-
const
|
|
39
|
+
// Extract private key for service worker initialization
|
|
40
|
+
const privateKey = identity.toHex();
|
|
41
|
+
// Create the wallet instance
|
|
42
|
+
const wallet = new ServiceWorkerWallet(options.serviceWorker, identity, walletRepo, contractRepo);
|
|
43
|
+
// Initialize the service worker with the config
|
|
44
|
+
const initMessage = {
|
|
70
45
|
type: "INIT_WALLET",
|
|
71
46
|
id: getRandomId(),
|
|
72
|
-
privateKey
|
|
73
|
-
arkServerUrl:
|
|
74
|
-
arkServerPublicKey:
|
|
47
|
+
privateKey,
|
|
48
|
+
arkServerUrl: options.arkServerUrl,
|
|
49
|
+
arkServerPublicKey: options.arkServerPublicKey,
|
|
75
50
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.cachedXOnlyPublicKey =
|
|
80
|
-
SingleKey.fromPrivateKey(privKeyBytes).xOnlyPublicKey();
|
|
51
|
+
// Initialize the service worker
|
|
52
|
+
await wallet.sendMessage(initMessage);
|
|
53
|
+
return wallet;
|
|
81
54
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Simplified setup method that handles service worker registration,
|
|
57
|
+
* identity creation, and wallet initialization automatically.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // One-liner setup - handles everything automatically!
|
|
62
|
+
* const wallet = await ServiceWorkerWallet.setup({
|
|
63
|
+
* serviceWorkerPath: '/service-worker.js',
|
|
64
|
+
* arkServerUrl: 'https://mutinynet.arkade.sh'
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* // With custom identity
|
|
68
|
+
* const identity = SingleKey.fromHex('your_private_key_hex');
|
|
69
|
+
* const wallet = await ServiceWorkerWallet.setup({
|
|
70
|
+
* serviceWorkerPath: '/service-worker.js',
|
|
71
|
+
* arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
72
|
+
* identity
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
static async setup(options) {
|
|
77
|
+
// Register and setup the service worker
|
|
78
|
+
const serviceWorker = await setupServiceWorker(options.serviceWorkerPath);
|
|
79
|
+
// Use the existing create method
|
|
80
|
+
return await ServiceWorkerWallet.create({
|
|
81
|
+
arkServerPublicKey: options.arkServerPublicKey,
|
|
82
|
+
arkServerUrl: options.arkServerUrl,
|
|
83
|
+
esploraUrl: options.esploraUrl,
|
|
84
|
+
identity: options.identity,
|
|
85
|
+
serviceWorker,
|
|
86
|
+
storage: options.storage,
|
|
87
|
+
});
|
|
90
88
|
}
|
|
91
89
|
// send a message and wait for a response
|
|
92
90
|
async sendMessage(message) {
|
|
@@ -112,6 +110,21 @@ export class ServiceWorkerWallet {
|
|
|
112
110
|
this.serviceWorker.postMessage(message);
|
|
113
111
|
});
|
|
114
112
|
}
|
|
113
|
+
async clear() {
|
|
114
|
+
const message = {
|
|
115
|
+
type: "CLEAR",
|
|
116
|
+
id: getRandomId(),
|
|
117
|
+
};
|
|
118
|
+
// Clear page-side storage to maintain parity with SW
|
|
119
|
+
try {
|
|
120
|
+
const address = await this.getAddress();
|
|
121
|
+
await this.walletRepository.clearVtxos(address);
|
|
122
|
+
}
|
|
123
|
+
catch (_) {
|
|
124
|
+
console.warn("Failed to clear vtxos from wallet repository");
|
|
125
|
+
}
|
|
126
|
+
await this.sendMessage(message);
|
|
127
|
+
}
|
|
115
128
|
async getAddress() {
|
|
116
129
|
const message = {
|
|
117
130
|
type: "GET_ADDRESS",
|
|
@@ -160,37 +173,64 @@ export class ServiceWorkerWallet {
|
|
|
160
173
|
throw new Error(`Failed to get balance: ${error}`);
|
|
161
174
|
}
|
|
162
175
|
}
|
|
163
|
-
async
|
|
176
|
+
async getBoardingUtxos() {
|
|
164
177
|
const message = {
|
|
165
|
-
type: "
|
|
178
|
+
type: "GET_BOARDING_UTXOS",
|
|
166
179
|
id: getRandomId(),
|
|
167
|
-
filter,
|
|
168
180
|
};
|
|
169
181
|
try {
|
|
170
182
|
const response = await this.sendMessage(message);
|
|
171
|
-
if (Response.
|
|
172
|
-
return response.
|
|
183
|
+
if (Response.isBoardingUtxos(response)) {
|
|
184
|
+
return response.boardingUtxos;
|
|
173
185
|
}
|
|
174
186
|
throw new UnexpectedResponseError(response);
|
|
175
187
|
}
|
|
176
188
|
catch (error) {
|
|
177
|
-
throw new Error(`Failed to get
|
|
189
|
+
throw new Error(`Failed to get boarding UTXOs: ${error}`);
|
|
178
190
|
}
|
|
179
191
|
}
|
|
180
|
-
async
|
|
192
|
+
async getStatus() {
|
|
181
193
|
const message = {
|
|
182
|
-
type: "
|
|
194
|
+
type: "GET_STATUS",
|
|
195
|
+
id: getRandomId(),
|
|
196
|
+
};
|
|
197
|
+
const response = await this.sendMessage(message);
|
|
198
|
+
if (Response.isWalletStatus(response)) {
|
|
199
|
+
return response.status;
|
|
200
|
+
}
|
|
201
|
+
throw new UnexpectedResponseError(response);
|
|
202
|
+
}
|
|
203
|
+
async getTransactionHistory() {
|
|
204
|
+
const message = {
|
|
205
|
+
type: "GET_TRANSACTION_HISTORY",
|
|
183
206
|
id: getRandomId(),
|
|
184
207
|
};
|
|
185
208
|
try {
|
|
186
209
|
const response = await this.sendMessage(message);
|
|
187
|
-
if (Response.
|
|
188
|
-
return response.
|
|
210
|
+
if (Response.isTransactionHistory(response)) {
|
|
211
|
+
return response.transactions;
|
|
189
212
|
}
|
|
190
213
|
throw new UnexpectedResponseError(response);
|
|
191
214
|
}
|
|
192
215
|
catch (error) {
|
|
193
|
-
throw new Error(`Failed to get
|
|
216
|
+
throw new Error(`Failed to get transaction history: ${error}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async getVtxos(filter) {
|
|
220
|
+
const message = {
|
|
221
|
+
type: "GET_VTXOS",
|
|
222
|
+
id: getRandomId(),
|
|
223
|
+
filter,
|
|
224
|
+
};
|
|
225
|
+
try {
|
|
226
|
+
const response = await this.sendMessage(message);
|
|
227
|
+
if (Response.isVtxos(response)) {
|
|
228
|
+
return response.vtxos;
|
|
229
|
+
}
|
|
230
|
+
throw new UnexpectedResponseError(response);
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
throw new Error(`Failed to get vtxos: ${error}`);
|
|
194
234
|
}
|
|
195
235
|
}
|
|
196
236
|
async sendBitcoin(params) {
|
|
@@ -247,52 +287,6 @@ export class ServiceWorkerWallet {
|
|
|
247
287
|
throw new Error(`Settlement failed: ${error}`);
|
|
248
288
|
}
|
|
249
289
|
}
|
|
250
|
-
async getTransactionHistory() {
|
|
251
|
-
const message = {
|
|
252
|
-
type: "GET_TRANSACTION_HISTORY",
|
|
253
|
-
id: getRandomId(),
|
|
254
|
-
};
|
|
255
|
-
try {
|
|
256
|
-
const response = await this.sendMessage(message);
|
|
257
|
-
if (Response.isTransactionHistory(response)) {
|
|
258
|
-
return response.transactions;
|
|
259
|
-
}
|
|
260
|
-
throw new UnexpectedResponseError(response);
|
|
261
|
-
}
|
|
262
|
-
catch (error) {
|
|
263
|
-
throw new Error(`Failed to get transaction history: ${error}`);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
xOnlyPublicKey() {
|
|
267
|
-
if (!this.cachedXOnlyPublicKey) {
|
|
268
|
-
throw new Error("Wallet not initialized");
|
|
269
|
-
}
|
|
270
|
-
return this.cachedXOnlyPublicKey;
|
|
271
|
-
}
|
|
272
|
-
signerSession() {
|
|
273
|
-
return TreeSignerSession.random();
|
|
274
|
-
}
|
|
275
|
-
async sign(tx, inputIndexes) {
|
|
276
|
-
const message = {
|
|
277
|
-
type: "SIGN",
|
|
278
|
-
tx: base64.encode(tx.toPSBT()),
|
|
279
|
-
inputIndexes,
|
|
280
|
-
id: getRandomId(),
|
|
281
|
-
};
|
|
282
|
-
try {
|
|
283
|
-
const response = await this.sendMessage(message);
|
|
284
|
-
if (Response.isSignSuccess(response)) {
|
|
285
|
-
return Transaction.fromPSBT(base64.decode(response.tx), {
|
|
286
|
-
allowUnknown: true,
|
|
287
|
-
allowUnknownInputs: true,
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
throw new UnexpectedResponseError(response);
|
|
291
|
-
}
|
|
292
|
-
catch (error) {
|
|
293
|
-
throw new Error(`Failed to sign: ${error}`);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
290
|
}
|
|
297
291
|
function getRandomId() {
|
|
298
292
|
const randomValue = crypto.getRandomValues(new Uint8Array(16));
|