@arkade-os/sdk 0.1.4 → 0.2.1
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 +157 -174
- package/dist/cjs/arknote/index.js +61 -58
- package/dist/cjs/bip322/errors.js +13 -0
- package/dist/cjs/bip322/index.js +178 -0
- package/dist/cjs/forfeit.js +14 -25
- package/dist/cjs/identity/singleKey.js +68 -0
- package/dist/cjs/index.js +43 -17
- package/dist/cjs/providers/ark.js +261 -321
- package/dist/cjs/providers/indexer.js +525 -0
- package/dist/cjs/providers/onchain.js +193 -15
- package/dist/cjs/script/address.js +48 -17
- package/dist/cjs/script/base.js +120 -3
- package/dist/cjs/script/default.js +18 -4
- package/dist/cjs/script/tapscript.js +61 -20
- package/dist/cjs/script/vhtlc.js +85 -7
- package/dist/cjs/tree/signingSession.js +63 -106
- package/dist/cjs/tree/txTree.js +193 -0
- package/dist/cjs/tree/validation.js +79 -155
- package/dist/cjs/utils/anchor.js +35 -0
- package/dist/cjs/utils/arkTransaction.js +108 -0
- package/dist/cjs/utils/transactionHistory.js +84 -72
- package/dist/cjs/utils/txSizeEstimator.js +12 -0
- package/dist/cjs/utils/unknownFields.js +211 -0
- package/dist/cjs/wallet/index.js +12 -0
- package/dist/cjs/wallet/onchain.js +201 -0
- package/dist/cjs/wallet/ramps.js +95 -0
- package/dist/cjs/wallet/serviceWorker/db/vtxo/idb.js +32 -0
- package/dist/cjs/wallet/serviceWorker/request.js +15 -12
- package/dist/cjs/wallet/serviceWorker/response.js +22 -27
- package/dist/cjs/wallet/serviceWorker/utils.js +8 -0
- package/dist/cjs/wallet/serviceWorker/wallet.js +61 -34
- package/dist/cjs/wallet/serviceWorker/worker.js +120 -108
- package/dist/cjs/wallet/unroll.js +270 -0
- package/dist/cjs/wallet/wallet.js +701 -454
- package/dist/esm/arknote/index.js +61 -57
- package/dist/esm/bip322/errors.js +9 -0
- package/dist/esm/bip322/index.js +174 -0
- package/dist/esm/forfeit.js +15 -26
- package/dist/esm/identity/singleKey.js +64 -0
- package/dist/esm/index.js +31 -12
- package/dist/esm/providers/ark.js +259 -320
- package/dist/esm/providers/indexer.js +521 -0
- package/dist/esm/providers/onchain.js +193 -15
- package/dist/esm/script/address.js +48 -17
- package/dist/esm/script/base.js +120 -3
- package/dist/esm/script/default.js +18 -4
- package/dist/esm/script/tapscript.js +61 -20
- package/dist/esm/script/vhtlc.js +85 -7
- package/dist/esm/tree/signingSession.js +65 -108
- package/dist/esm/tree/txTree.js +189 -0
- package/dist/esm/tree/validation.js +75 -152
- package/dist/esm/utils/anchor.js +31 -0
- package/dist/esm/utils/arkTransaction.js +105 -0
- package/dist/esm/utils/transactionHistory.js +84 -72
- package/dist/esm/utils/txSizeEstimator.js +12 -0
- package/dist/esm/utils/unknownFields.js +173 -0
- package/dist/esm/wallet/index.js +9 -0
- package/dist/esm/wallet/onchain.js +196 -0
- package/dist/esm/wallet/ramps.js +91 -0
- package/dist/esm/wallet/serviceWorker/db/vtxo/idb.js +32 -0
- package/dist/esm/wallet/serviceWorker/request.js +15 -12
- package/dist/esm/wallet/serviceWorker/response.js +22 -27
- package/dist/esm/wallet/serviceWorker/utils.js +8 -0
- package/dist/esm/wallet/serviceWorker/wallet.js +62 -35
- package/dist/esm/wallet/serviceWorker/worker.js +120 -108
- package/dist/esm/wallet/unroll.js +267 -0
- package/dist/esm/wallet/wallet.js +674 -461
- package/dist/types/arknote/index.d.ts +40 -13
- package/dist/types/bip322/errors.d.ts +6 -0
- package/dist/types/bip322/index.d.ts +57 -0
- package/dist/types/forfeit.d.ts +2 -14
- package/dist/types/identity/singleKey.d.ts +27 -0
- package/dist/types/index.d.ts +24 -12
- package/dist/types/providers/ark.d.ts +114 -95
- package/dist/types/providers/indexer.d.ts +186 -0
- package/dist/types/providers/onchain.d.ts +41 -11
- package/dist/types/script/address.d.ts +26 -2
- package/dist/types/script/base.d.ts +13 -3
- package/dist/types/script/default.d.ts +22 -0
- package/dist/types/script/tapscript.d.ts +61 -5
- package/dist/types/script/vhtlc.d.ts +27 -0
- package/dist/types/tree/signingSession.d.ts +5 -5
- package/dist/types/tree/txTree.d.ts +28 -0
- package/dist/types/tree/validation.d.ts +15 -22
- package/dist/types/utils/anchor.d.ts +19 -0
- package/dist/types/utils/arkTransaction.d.ts +27 -0
- package/dist/types/utils/transactionHistory.d.ts +7 -1
- package/dist/types/utils/txSizeEstimator.d.ts +3 -0
- package/dist/types/utils/unknownFields.d.ts +83 -0
- package/dist/types/wallet/index.d.ts +51 -50
- package/dist/types/wallet/onchain.d.ts +49 -0
- package/dist/types/wallet/ramps.d.ts +32 -0
- package/dist/types/wallet/serviceWorker/db/vtxo/idb.d.ts +2 -0
- package/dist/types/wallet/serviceWorker/db/vtxo/index.d.ts +2 -0
- package/dist/types/wallet/serviceWorker/request.d.ts +14 -16
- package/dist/types/wallet/serviceWorker/response.d.ts +17 -19
- package/dist/types/wallet/serviceWorker/utils.d.ts +8 -0
- package/dist/types/wallet/serviceWorker/wallet.d.ts +36 -8
- package/dist/types/wallet/serviceWorker/worker.d.ts +7 -3
- package/dist/types/wallet/unroll.d.ts +102 -0
- package/dist/types/wallet/wallet.d.ts +71 -25
- package/package.json +37 -35
- package/dist/cjs/identity/inMemoryKey.js +0 -40
- package/dist/cjs/tree/vtxoTree.js +0 -231
- package/dist/cjs/utils/coinselect.js +0 -73
- package/dist/cjs/utils/psbt.js +0 -137
- package/dist/esm/identity/inMemoryKey.js +0 -36
- package/dist/esm/tree/vtxoTree.js +0 -191
- package/dist/esm/utils/coinselect.js +0 -69
- package/dist/esm/utils/psbt.js +0 -131
- package/dist/types/identity/inMemoryKey.d.ts +0 -12
- package/dist/types/tree/vtxoTree.d.ts +0 -33
- package/dist/types/utils/coinselect.d.ts +0 -21
- package/dist/types/utils/psbt.d.ts +0 -11
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Ramps = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Ramps is a class wrapping IWallet.settle method to provide a more convenient interface for onboarding and offboarding operations.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const ramps = new Ramps(wallet);
|
|
10
|
+
* await ramps.onboard(); // onboard all boarding utxos
|
|
11
|
+
* await ramps.offboard(myOnchainAddress); // collaborative exit all vtxos to onchain address
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
class Ramps {
|
|
15
|
+
constructor(wallet) {
|
|
16
|
+
this.wallet = wallet;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Onboard boarding utxos.
|
|
20
|
+
*
|
|
21
|
+
* @param boardingUtxos - The boarding utxos to onboard. If not provided, all boarding utxos will be used.
|
|
22
|
+
* @param amount - The amount to onboard. If not provided, the total amount of boarding utxos will be onboarded.
|
|
23
|
+
* @param eventCallback - The callback to receive settlement events. optional.
|
|
24
|
+
*/
|
|
25
|
+
async onboard(boardingUtxos, amount, eventCallback) {
|
|
26
|
+
boardingUtxos = boardingUtxos ?? (await this.wallet.getBoardingUtxos());
|
|
27
|
+
const totalAmount = boardingUtxos.reduce((acc, coin) => acc + BigInt(coin.value), 0n);
|
|
28
|
+
let change = 0n;
|
|
29
|
+
if (amount) {
|
|
30
|
+
if (amount > totalAmount) {
|
|
31
|
+
throw new Error("Amount is greater than total amount of boarding utxos");
|
|
32
|
+
}
|
|
33
|
+
change = totalAmount - amount;
|
|
34
|
+
}
|
|
35
|
+
amount = amount ?? totalAmount;
|
|
36
|
+
const offchainAddress = await this.wallet.getAddress();
|
|
37
|
+
const outputs = [
|
|
38
|
+
{
|
|
39
|
+
address: offchainAddress,
|
|
40
|
+
amount,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
if (change > 0n) {
|
|
44
|
+
const boardingAddress = await this.wallet.getBoardingAddress();
|
|
45
|
+
outputs.push({
|
|
46
|
+
address: boardingAddress,
|
|
47
|
+
amount: change,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return this.wallet.settle({
|
|
51
|
+
inputs: boardingUtxos,
|
|
52
|
+
outputs,
|
|
53
|
+
}, eventCallback);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Offboard vtxos, or "collaborative exit" vtxos to onchain address.
|
|
57
|
+
*
|
|
58
|
+
* @param destinationAddress - The destination address to offboard to.
|
|
59
|
+
* @param amount - The amount to offboard. If not provided, the total amount of vtxos will be offboarded.
|
|
60
|
+
* @param eventCallback - The callback to receive settlement events. optional.
|
|
61
|
+
*/
|
|
62
|
+
async offboard(destinationAddress, amount, eventCallback) {
|
|
63
|
+
const vtxos = await this.wallet.getVtxos({
|
|
64
|
+
withRecoverable: true,
|
|
65
|
+
withUnrolled: false,
|
|
66
|
+
});
|
|
67
|
+
const totalAmount = vtxos.reduce((acc, coin) => acc + BigInt(coin.value), 0n);
|
|
68
|
+
let change = 0n;
|
|
69
|
+
if (amount) {
|
|
70
|
+
if (amount > totalAmount) {
|
|
71
|
+
throw new Error("Amount is greater than total amount of vtxos");
|
|
72
|
+
}
|
|
73
|
+
change = totalAmount - amount;
|
|
74
|
+
}
|
|
75
|
+
amount = amount ?? totalAmount;
|
|
76
|
+
const outputs = [
|
|
77
|
+
{
|
|
78
|
+
address: destinationAddress,
|
|
79
|
+
amount,
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
if (change > 0n) {
|
|
83
|
+
const offchainAddress = await this.wallet.getAddress();
|
|
84
|
+
outputs.push({
|
|
85
|
+
address: offchainAddress,
|
|
86
|
+
amount: change,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return this.wallet.settle({
|
|
90
|
+
inputs: vtxos,
|
|
91
|
+
outputs,
|
|
92
|
+
}, eventCallback);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.Ramps = Ramps;
|
|
@@ -111,6 +111,38 @@ class IndexedDBVtxoRepository {
|
|
|
111
111
|
request.onerror = () => reject(request.error);
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
|
+
async getSweptVtxos() {
|
|
115
|
+
if (!this.db) {
|
|
116
|
+
throw new Error("Database not opened");
|
|
117
|
+
}
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
const transaction = this.db.transaction(IndexedDBVtxoRepository.STORE_NAME, "readonly");
|
|
120
|
+
const store = transaction.objectStore(IndexedDBVtxoRepository.STORE_NAME);
|
|
121
|
+
const stateIndex = store.index("state");
|
|
122
|
+
// Get vtxos where state is "swept"
|
|
123
|
+
const request = stateIndex.getAll(IDBKeyRange.only("swept"));
|
|
124
|
+
request.onsuccess = () => {
|
|
125
|
+
resolve(request.result);
|
|
126
|
+
};
|
|
127
|
+
request.onerror = () => reject(request.error);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
async getSpentVtxos() {
|
|
131
|
+
if (!this.db) {
|
|
132
|
+
throw new Error("Database not opened");
|
|
133
|
+
}
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
const transaction = this.db.transaction(IndexedDBVtxoRepository.STORE_NAME, "readonly");
|
|
136
|
+
const store = transaction.objectStore(IndexedDBVtxoRepository.STORE_NAME);
|
|
137
|
+
const spentByIndex = store.index("spentBy");
|
|
138
|
+
// Get vtxos where spentBy is not empty string
|
|
139
|
+
const request = spentByIndex.getAll(IDBKeyRange.lowerBound("", true));
|
|
140
|
+
request.onsuccess = () => {
|
|
141
|
+
resolve(request.result);
|
|
142
|
+
};
|
|
143
|
+
request.onerror = () => reject(request.error);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
114
146
|
async getAllVtxos() {
|
|
115
147
|
if (!this.db) {
|
|
116
148
|
throw new Error("Database not opened");
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Request = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Request is the namespace that contains the request types for the service worker.
|
|
6
|
+
*/
|
|
4
7
|
var Request;
|
|
5
8
|
(function (Request) {
|
|
6
9
|
function isBase(message) {
|
|
@@ -13,8 +16,6 @@ var Request;
|
|
|
13
16
|
typeof message.privateKey === "string" &&
|
|
14
17
|
"arkServerUrl" in message &&
|
|
15
18
|
typeof message.arkServerUrl === "string" &&
|
|
16
|
-
"network" in message &&
|
|
17
|
-
typeof message.network === "string" &&
|
|
18
19
|
("arkServerPublicKey" in message
|
|
19
20
|
? typeof message.arkServerPublicKey === "string" ||
|
|
20
21
|
message.arkServerPublicKey === undefined
|
|
@@ -29,18 +30,14 @@ var Request;
|
|
|
29
30
|
return message.type === "GET_ADDRESS";
|
|
30
31
|
}
|
|
31
32
|
Request.isGetAddress = isGetAddress;
|
|
32
|
-
function
|
|
33
|
-
return message.type === "
|
|
33
|
+
function isGetBoardingAddress(message) {
|
|
34
|
+
return message.type === "GET_BOARDING_ADDRESS";
|
|
34
35
|
}
|
|
35
|
-
Request.
|
|
36
|
+
Request.isGetBoardingAddress = isGetBoardingAddress;
|
|
36
37
|
function isGetBalance(message) {
|
|
37
38
|
return message.type === "GET_BALANCE";
|
|
38
39
|
}
|
|
39
40
|
Request.isGetBalance = isGetBalance;
|
|
40
|
-
function isGetCoins(message) {
|
|
41
|
-
return message.type === "GET_COINS";
|
|
42
|
-
}
|
|
43
|
-
Request.isGetCoins = isGetCoins;
|
|
44
41
|
function isGetVtxos(message) {
|
|
45
42
|
return message.type === "GET_VTXOS";
|
|
46
43
|
}
|
|
@@ -72,8 +69,14 @@ var Request;
|
|
|
72
69
|
return message.type === "GET_STATUS";
|
|
73
70
|
}
|
|
74
71
|
Request.isGetStatus = isGetStatus;
|
|
75
|
-
function
|
|
76
|
-
return message.type === "
|
|
72
|
+
function isSign(message) {
|
|
73
|
+
return (message.type === "SIGN" &&
|
|
74
|
+
"tx" in message &&
|
|
75
|
+
typeof message.tx === "string" &&
|
|
76
|
+
("inputIndexes" in message && message.inputIndexes != undefined
|
|
77
|
+
? Array.isArray(message.inputIndexes) &&
|
|
78
|
+
message.inputIndexes.every((index) => typeof index === "number")
|
|
79
|
+
: true));
|
|
77
80
|
}
|
|
78
|
-
Request.
|
|
81
|
+
Request.isSign = isSign;
|
|
79
82
|
})(Request || (exports.Request = Request = {}));
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Response = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Response is the namespace that contains the response types for the service worker.
|
|
6
|
+
*/
|
|
4
7
|
var Response;
|
|
5
8
|
(function (Response) {
|
|
6
9
|
Response.walletInitialized = (id) => ({
|
|
@@ -43,28 +46,28 @@ var Response;
|
|
|
43
46
|
return response.type === "ADDRESS" && response.success === true;
|
|
44
47
|
}
|
|
45
48
|
Response.isAddress = isAddress;
|
|
46
|
-
function
|
|
49
|
+
function isBoardingAddress(response) {
|
|
50
|
+
return (response.type === "BOARDING_ADDRESS" && response.success === true);
|
|
51
|
+
}
|
|
52
|
+
Response.isBoardingAddress = isBoardingAddress;
|
|
53
|
+
function address(id, address) {
|
|
47
54
|
return {
|
|
48
55
|
type: "ADDRESS",
|
|
49
56
|
success: true,
|
|
50
|
-
|
|
57
|
+
address,
|
|
51
58
|
id,
|
|
52
59
|
};
|
|
53
60
|
}
|
|
54
|
-
Response.
|
|
55
|
-
function
|
|
56
|
-
return response.type === "ADDRESS_INFO" && response.success === true;
|
|
57
|
-
}
|
|
58
|
-
Response.isAddressInfo = isAddressInfo;
|
|
59
|
-
function addressInfo(id, addressInfo) {
|
|
61
|
+
Response.address = address;
|
|
62
|
+
function boardingAddress(id, address) {
|
|
60
63
|
return {
|
|
61
|
-
type: "
|
|
64
|
+
type: "BOARDING_ADDRESS",
|
|
62
65
|
success: true,
|
|
63
|
-
|
|
66
|
+
address,
|
|
64
67
|
id,
|
|
65
68
|
};
|
|
66
69
|
}
|
|
67
|
-
Response.
|
|
70
|
+
Response.boardingAddress = boardingAddress;
|
|
68
71
|
function isBalance(response) {
|
|
69
72
|
return response.type === "BALANCE" && response.success === true;
|
|
70
73
|
}
|
|
@@ -78,19 +81,6 @@ var Response;
|
|
|
78
81
|
};
|
|
79
82
|
}
|
|
80
83
|
Response.balance = balance;
|
|
81
|
-
function isCoins(response) {
|
|
82
|
-
return response.type === "COINS" && response.success === true;
|
|
83
|
-
}
|
|
84
|
-
Response.isCoins = isCoins;
|
|
85
|
-
function coins(id, coins) {
|
|
86
|
-
return {
|
|
87
|
-
type: "COINS",
|
|
88
|
-
success: true,
|
|
89
|
-
coins,
|
|
90
|
-
id,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
Response.coins = coins;
|
|
94
84
|
function isVtxos(response) {
|
|
95
85
|
return response.type === "VTXOS" && response.success === true;
|
|
96
86
|
}
|
|
@@ -184,12 +174,17 @@ var Response;
|
|
|
184
174
|
};
|
|
185
175
|
}
|
|
186
176
|
Response.clearResponse = clearResponse;
|
|
187
|
-
function
|
|
177
|
+
function signSuccess(id, tx) {
|
|
188
178
|
return {
|
|
189
|
-
type: "
|
|
179
|
+
type: "SIGN_SUCCESS",
|
|
190
180
|
success: true,
|
|
181
|
+
tx,
|
|
191
182
|
id,
|
|
192
183
|
};
|
|
193
184
|
}
|
|
194
|
-
Response.
|
|
185
|
+
Response.signSuccess = signSuccess;
|
|
186
|
+
function isSignSuccess(response) {
|
|
187
|
+
return response.type === "SIGN_SUCCESS" && response.success === true;
|
|
188
|
+
}
|
|
189
|
+
Response.isSignSuccess = isSignSuccess;
|
|
195
190
|
})(Response || (exports.Response = Response = {}));
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setupServiceWorker = setupServiceWorker;
|
|
4
|
+
/**
|
|
5
|
+
* setupServiceWorker sets up the service worker.
|
|
6
|
+
* @param path - the path to the service worker script
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const serviceWorker = await setupServiceWorker("/service-worker.js");
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
4
12
|
async function setupServiceWorker(path) {
|
|
5
13
|
// check if service workers are supported
|
|
6
14
|
if (!("serviceWorker" in navigator)) {
|
|
@@ -3,13 +3,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ServiceWorkerWallet = void 0;
|
|
4
4
|
const response_1 = require("./response");
|
|
5
5
|
const base_1 = require("@scure/base");
|
|
6
|
+
const singleKey_1 = require("../../identity/singleKey");
|
|
7
|
+
const signingSession_1 = require("../../tree/signingSession");
|
|
8
|
+
const btc_signer_1 = require("@scure/btc-signer");
|
|
6
9
|
class UnexpectedResponseError extends Error {
|
|
7
10
|
constructor(response) {
|
|
8
11
|
super(`Unexpected response type. Got: ${JSON.stringify(response, null, 2)}`);
|
|
9
12
|
this.name = "UnexpectedResponseError";
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Service Worker-based wallet implementation for browser environments.
|
|
17
|
+
*
|
|
18
|
+
* This wallet uses a service worker as a backend to handle wallet logic,
|
|
19
|
+
* providing secure key storage and transaction signing in web applications.
|
|
20
|
+
* The service worker runs in a separate thread and can persist data between
|
|
21
|
+
* browser sessions.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Create and initialize the service worker wallet
|
|
26
|
+
* const serviceWorker = await setupServiceWorker("/service-worker.js");
|
|
27
|
+
* const wallet = new ServiceWorkerWallet(serviceWorker);
|
|
28
|
+
* await wallet.init({
|
|
29
|
+
* privateKey: 'your_private_key_hex',
|
|
30
|
+
* arkServerUrl: 'https://ark.example.com'
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Use like any other wallet
|
|
34
|
+
* const address = await wallet.getAddress();
|
|
35
|
+
* const balance = await wallet.getBalance();
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
13
38
|
class ServiceWorkerWallet {
|
|
14
39
|
constructor(serviceWorker) {
|
|
15
40
|
this.serviceWorker = serviceWorker;
|
|
@@ -44,11 +69,14 @@ class ServiceWorkerWallet {
|
|
|
44
69
|
type: "INIT_WALLET",
|
|
45
70
|
id: getRandomId(),
|
|
46
71
|
privateKey: config.privateKey,
|
|
47
|
-
|
|
48
|
-
arkServerUrl: config.arkServerUrl || "",
|
|
72
|
+
arkServerUrl: config.arkServerUrl,
|
|
49
73
|
arkServerPublicKey: config.arkServerPublicKey,
|
|
50
74
|
};
|
|
51
75
|
await this.sendMessage(message);
|
|
76
|
+
const privKeyBytes = base_1.hex.decode(config.privateKey);
|
|
77
|
+
// cache the identity xOnlyPublicKey
|
|
78
|
+
this.cachedXOnlyPublicKey =
|
|
79
|
+
singleKey_1.SingleKey.fromPrivateKey(privKeyBytes).xOnlyPublicKey();
|
|
52
80
|
}
|
|
53
81
|
async clear() {
|
|
54
82
|
const message = {
|
|
@@ -56,6 +84,8 @@ class ServiceWorkerWallet {
|
|
|
56
84
|
id: getRandomId(),
|
|
57
85
|
};
|
|
58
86
|
await this.sendMessage(message);
|
|
87
|
+
// clear the cached xOnlyPublicKey
|
|
88
|
+
this.cachedXOnlyPublicKey = undefined;
|
|
59
89
|
}
|
|
60
90
|
// send a message and wait for a response
|
|
61
91
|
async sendMessage(message) {
|
|
@@ -89,7 +119,7 @@ class ServiceWorkerWallet {
|
|
|
89
119
|
try {
|
|
90
120
|
const response = await this.sendMessage(message);
|
|
91
121
|
if (response_1.Response.isAddress(response)) {
|
|
92
|
-
return response.
|
|
122
|
+
return response.address;
|
|
93
123
|
}
|
|
94
124
|
throw new UnexpectedResponseError(response);
|
|
95
125
|
}
|
|
@@ -97,20 +127,20 @@ class ServiceWorkerWallet {
|
|
|
97
127
|
throw new Error(`Failed to get address: ${error}`);
|
|
98
128
|
}
|
|
99
129
|
}
|
|
100
|
-
async
|
|
130
|
+
async getBoardingAddress() {
|
|
101
131
|
const message = {
|
|
102
|
-
type: "
|
|
132
|
+
type: "GET_BOARDING_ADDRESS",
|
|
103
133
|
id: getRandomId(),
|
|
104
134
|
};
|
|
105
135
|
try {
|
|
106
136
|
const response = await this.sendMessage(message);
|
|
107
|
-
if (response_1.Response.
|
|
108
|
-
return response.
|
|
137
|
+
if (response_1.Response.isBoardingAddress(response)) {
|
|
138
|
+
return response.address;
|
|
109
139
|
}
|
|
110
140
|
throw new UnexpectedResponseError(response);
|
|
111
141
|
}
|
|
112
142
|
catch (error) {
|
|
113
|
-
throw new Error(`Failed to get address
|
|
143
|
+
throw new Error(`Failed to get boarding address: ${error}`);
|
|
114
144
|
}
|
|
115
145
|
}
|
|
116
146
|
async getBalance() {
|
|
@@ -129,26 +159,11 @@ class ServiceWorkerWallet {
|
|
|
129
159
|
throw new Error(`Failed to get balance: ${error}`);
|
|
130
160
|
}
|
|
131
161
|
}
|
|
132
|
-
async
|
|
133
|
-
const message = {
|
|
134
|
-
type: "GET_COINS",
|
|
135
|
-
id: getRandomId(),
|
|
136
|
-
};
|
|
137
|
-
try {
|
|
138
|
-
const response = await this.sendMessage(message);
|
|
139
|
-
if (response_1.Response.isCoins(response)) {
|
|
140
|
-
return response.coins;
|
|
141
|
-
}
|
|
142
|
-
throw new UnexpectedResponseError(response);
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
throw new Error(`Failed to get coins: ${error}`);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
async getVtxos() {
|
|
162
|
+
async getVtxos(filter) {
|
|
149
163
|
const message = {
|
|
150
164
|
type: "GET_VTXOS",
|
|
151
165
|
id: getRandomId(),
|
|
166
|
+
filter,
|
|
152
167
|
};
|
|
153
168
|
try {
|
|
154
169
|
const response = await this.sendMessage(message);
|
|
@@ -177,11 +192,10 @@ class ServiceWorkerWallet {
|
|
|
177
192
|
throw new Error(`Failed to get boarding UTXOs: ${error}`);
|
|
178
193
|
}
|
|
179
194
|
}
|
|
180
|
-
async sendBitcoin(params
|
|
195
|
+
async sendBitcoin(params) {
|
|
181
196
|
const message = {
|
|
182
197
|
type: "SEND_BITCOIN",
|
|
183
198
|
params,
|
|
184
|
-
zeroFee,
|
|
185
199
|
id: getRandomId(),
|
|
186
200
|
};
|
|
187
201
|
try {
|
|
@@ -248,21 +262,34 @@ class ServiceWorkerWallet {
|
|
|
248
262
|
throw new Error(`Failed to get transaction history: ${error}`);
|
|
249
263
|
}
|
|
250
264
|
}
|
|
251
|
-
|
|
265
|
+
xOnlyPublicKey() {
|
|
266
|
+
if (!this.cachedXOnlyPublicKey) {
|
|
267
|
+
throw new Error("Wallet not initialized");
|
|
268
|
+
}
|
|
269
|
+
return this.cachedXOnlyPublicKey;
|
|
270
|
+
}
|
|
271
|
+
signerSession() {
|
|
272
|
+
return signingSession_1.TreeSignerSession.random();
|
|
273
|
+
}
|
|
274
|
+
async sign(tx, inputIndexes) {
|
|
252
275
|
const message = {
|
|
253
|
-
type: "
|
|
254
|
-
|
|
276
|
+
type: "SIGN",
|
|
277
|
+
tx: base_1.base64.encode(tx.toPSBT()),
|
|
278
|
+
inputIndexes,
|
|
255
279
|
id: getRandomId(),
|
|
256
280
|
};
|
|
257
281
|
try {
|
|
258
282
|
const response = await this.sendMessage(message);
|
|
259
|
-
if (response
|
|
260
|
-
return
|
|
283
|
+
if (response_1.Response.isSignSuccess(response)) {
|
|
284
|
+
return btc_signer_1.Transaction.fromPSBT(base_1.base64.decode(response.tx), {
|
|
285
|
+
allowUnknown: true,
|
|
286
|
+
allowUnknownInputs: true,
|
|
287
|
+
});
|
|
261
288
|
}
|
|
262
289
|
throw new UnexpectedResponseError(response);
|
|
263
290
|
}
|
|
264
291
|
catch (error) {
|
|
265
|
-
throw new Error(`Failed to
|
|
292
|
+
throw new Error(`Failed to sign: ${error}`);
|
|
266
293
|
}
|
|
267
294
|
}
|
|
268
295
|
}
|