@arkade-os/sdk 0.3.0-alpha.8 → 0.3.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 +48 -14
- package/dist/cjs/arknote/index.js +3 -3
- package/dist/cjs/forfeit.js +2 -2
- package/dist/cjs/identity/singleKey.js +8 -8
- package/dist/cjs/index.js +13 -5
- package/dist/cjs/{bip322 → intent}/index.js +38 -61
- package/dist/cjs/musig2/index.js +2 -1
- package/dist/cjs/musig2/nonces.js +4 -0
- package/dist/cjs/providers/ark.js +76 -45
- package/dist/cjs/providers/errors.js +59 -0
- package/dist/cjs/providers/expoArk.js +15 -170
- package/dist/cjs/providers/expoIndexer.js +22 -111
- package/dist/cjs/providers/expoUtils.js +124 -0
- package/dist/cjs/providers/onchain.js +19 -20
- package/dist/cjs/repositories/walletRepository.js +64 -28
- package/dist/cjs/script/base.js +15 -7
- package/dist/cjs/script/tapscript.js +20 -21
- package/dist/cjs/script/vhtlc.js +2 -2
- package/dist/cjs/tree/signingSession.js +44 -11
- package/dist/cjs/tree/txTree.js +3 -4
- package/dist/cjs/tree/validation.js +2 -3
- package/dist/cjs/utils/arkTransaction.js +105 -15
- package/dist/cjs/utils/transaction.js +28 -0
- package/dist/cjs/utils/unknownFields.js +7 -7
- package/dist/cjs/wallet/onchain.js +6 -7
- package/dist/cjs/wallet/serviceWorker/response.js +32 -0
- package/dist/cjs/wallet/serviceWorker/utils.js +2 -0
- package/dist/cjs/wallet/serviceWorker/wallet.js +7 -8
- package/dist/cjs/wallet/serviceWorker/worker.js +46 -27
- package/dist/cjs/wallet/unroll.js +7 -9
- package/dist/cjs/wallet/utils.js +9 -0
- package/dist/cjs/wallet/vtxo-manager.js +323 -0
- package/dist/cjs/wallet/wallet.js +98 -125
- package/dist/esm/arknote/index.js +2 -2
- package/dist/esm/forfeit.js +1 -1
- package/dist/esm/identity/singleKey.js +9 -9
- package/dist/esm/index.js +14 -10
- package/dist/esm/{bip322 → intent}/index.js +32 -54
- package/dist/esm/musig2/index.js +1 -1
- package/dist/esm/musig2/nonces.js +3 -0
- package/dist/esm/providers/ark.js +76 -45
- package/dist/esm/providers/errors.js +54 -0
- package/dist/esm/providers/expoArk.js +15 -137
- package/dist/esm/providers/expoIndexer.js +22 -78
- package/dist/esm/providers/expoUtils.js +87 -0
- package/dist/esm/providers/onchain.js +19 -20
- package/dist/esm/repositories/walletRepository.js +64 -28
- package/dist/esm/script/base.js +12 -4
- package/dist/esm/script/tapscript.js +1 -2
- package/dist/esm/script/vhtlc.js +1 -1
- package/dist/esm/tree/signingSession.js +45 -12
- package/dist/esm/tree/txTree.js +3 -4
- package/dist/esm/tree/validation.js +2 -3
- package/dist/esm/utils/arkTransaction.js +97 -8
- package/dist/esm/utils/transaction.js +24 -0
- package/dist/esm/utils/unknownFields.js +3 -3
- package/dist/esm/wallet/onchain.js +3 -4
- package/dist/esm/wallet/serviceWorker/response.js +32 -0
- package/dist/esm/wallet/serviceWorker/utils.js +1 -0
- package/dist/esm/wallet/serviceWorker/wallet.js +8 -9
- package/dist/esm/wallet/serviceWorker/worker.js +48 -29
- package/dist/esm/wallet/unroll.js +5 -7
- package/dist/esm/wallet/utils.js +8 -0
- package/dist/esm/wallet/vtxo-manager.js +317 -0
- package/dist/esm/wallet/wallet.js +92 -119
- package/dist/types/arknote/index.d.ts +1 -1
- package/dist/types/forfeit.d.ts +2 -2
- package/dist/types/identity/index.d.ts +2 -2
- package/dist/types/identity/singleKey.d.ts +2 -2
- package/dist/types/index.d.ts +9 -7
- package/dist/types/intent/index.d.ts +41 -0
- package/dist/types/musig2/index.d.ts +1 -1
- package/dist/types/musig2/nonces.d.ts +1 -0
- package/dist/types/providers/ark.d.ts +62 -26
- package/dist/types/providers/errors.d.ts +13 -0
- package/dist/types/providers/expoIndexer.d.ts +2 -10
- package/dist/types/providers/expoUtils.d.ts +18 -0
- package/dist/types/providers/indexer.d.ts +1 -9
- package/dist/types/providers/onchain.d.ts +6 -2
- package/dist/types/repositories/walletRepository.d.ts +9 -5
- package/dist/types/script/base.d.ts +5 -2
- package/dist/types/tree/signingSession.d.ts +16 -11
- package/dist/types/utils/anchor.d.ts +2 -2
- package/dist/types/utils/arkTransaction.d.ts +12 -4
- package/dist/types/utils/transaction.d.ts +13 -0
- package/dist/types/utils/unknownFields.d.ts +4 -4
- package/dist/types/wallet/index.d.ts +6 -4
- package/dist/types/wallet/onchain.d.ts +1 -1
- package/dist/types/wallet/serviceWorker/response.d.ts +16 -2
- package/dist/types/wallet/serviceWorker/utils.d.ts +1 -0
- package/dist/types/wallet/serviceWorker/wallet.d.ts +2 -2
- package/dist/types/wallet/serviceWorker/worker.d.ts +7 -1
- package/dist/types/wallet/unroll.d.ts +1 -1
- package/dist/types/wallet/utils.d.ts +2 -1
- package/dist/types/wallet/vtxo-manager.d.ts +179 -0
- package/dist/types/wallet/wallet.d.ts +8 -4
- package/package.json +1 -2
- package/dist/cjs/bip322/errors.js +0 -13
- package/dist/esm/bip322/errors.js +0 -9
- package/dist/types/bip322/errors.d.ts +0 -6
- package/dist/types/bip322/index.d.ts +0 -57
package/README.md
CHANGED
|
@@ -108,26 +108,60 @@ const settleTxid = await wallet.settle({
|
|
|
108
108
|
})
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
### VTXO Management (Renewal & Recovery)
|
|
112
|
+
|
|
113
|
+
VTXOs have an expiration time (batch expiry). The SDK provides the `VtxoManager` class to handle both:
|
|
114
|
+
|
|
115
|
+
- **Renewal**: Renew VTXOs before they expire to maintain unilateral control of the funds.
|
|
116
|
+
- **Recovery**: Reclaim swept or expired VTXOs back to the wallet in case renewal window was missed.
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { VtxoManager } from '@arkade-os/sdk'
|
|
120
|
+
|
|
121
|
+
// Create manager with optional renewal configuration
|
|
122
|
+
const manager = new VtxoManager(wallet, {
|
|
123
|
+
enabled: true, // Enable expiration monitoring
|
|
124
|
+
thresholdPercentage: 10 // Alert when 10% of lifetime remains (default)
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Renewal: Prevent Expiration
|
|
129
|
+
|
|
130
|
+
Renew VTXOs before they expire to retain unilateral control of funds.
|
|
131
|
+
This settles expiring and recoverable VTXOs back to your wallet, refreshing their expiration time.
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// Renew all VTXOs to prevent expiration
|
|
135
|
+
const txid = await manager.renewVtxos()
|
|
136
|
+
console.log('Renewed:', txid)
|
|
137
|
+
|
|
138
|
+
// Check which VTXOs are expiring soon
|
|
139
|
+
const expiringVtxos = await manager.getExpiringVtxos()
|
|
140
|
+
// Override threshold percentage (e.g., renew when 5% of time remains)
|
|
141
|
+
const urgentlyExpiring = await manager.getExpiringVtxos(5)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
#### Recovery: Reclaim Swept VTXOs
|
|
146
|
+
|
|
147
|
+
Recover VTXOs that have been swept by the server or consolidate small amounts (subdust).
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Recover swept VTXOs and preconfirmed subdust
|
|
151
|
+
const txid = await manager.recoverVtxos((event) => {
|
|
152
|
+
console.log('Settlement event:', event.type)
|
|
153
|
+
})
|
|
154
|
+
console.log('Recovered:', txid)
|
|
155
|
+
// Check what's recoverable
|
|
156
|
+
const balance = await manager.getRecoverableBalance()
|
|
157
|
+
```
|
|
158
|
+
|
|
111
159
|
|
|
112
160
|
### Transaction History
|
|
113
161
|
|
|
114
162
|
```typescript
|
|
115
163
|
// Get transaction history
|
|
116
164
|
const history = await wallet.getTransactionHistory()
|
|
117
|
-
console.log('History:', history)
|
|
118
|
-
|
|
119
|
-
// Example history entry:
|
|
120
|
-
{
|
|
121
|
-
key: {
|
|
122
|
-
boardingTxid: '...', // for boarding transactions
|
|
123
|
-
commitmentTxid: '...', // for commitment transactions
|
|
124
|
-
redeemTxid: '...' // for regular transactions
|
|
125
|
-
},
|
|
126
|
-
type: TxType.TxReceived, // or TxType.TxSent
|
|
127
|
-
amount: 50000,
|
|
128
|
-
settled: true,
|
|
129
|
-
createdAt: 1234567890
|
|
130
|
-
}
|
|
131
165
|
```
|
|
132
166
|
|
|
133
167
|
### Offboarding
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ArkNote = void 0;
|
|
4
4
|
const base_1 = require("@scure/base");
|
|
5
|
-
const base_2 = require("../script/base");
|
|
6
5
|
const utils_js_1 = require("@scure/btc-signer/utils.js");
|
|
7
|
-
const
|
|
6
|
+
const btc_signer_1 = require("@scure/btc-signer");
|
|
7
|
+
const base_2 = require("../script/base");
|
|
8
8
|
/**
|
|
9
9
|
* ArkNotes are special virtual coins in the Ark protocol that can be created
|
|
10
10
|
* and spent without requiring any transactions. The server mints them, and they
|
|
@@ -85,5 +85,5 @@ function readUInt32BE(array, offset) {
|
|
|
85
85
|
return view.getUint32(0, false);
|
|
86
86
|
}
|
|
87
87
|
function noteTapscript(preimageHash) {
|
|
88
|
-
return
|
|
88
|
+
return btc_signer_1.Script.encode(["SHA256", preimageHash, "EQUAL"]);
|
|
89
89
|
}
|
package/dist/cjs/forfeit.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildForfeitTx = buildForfeitTx;
|
|
4
|
-
const
|
|
4
|
+
const transaction_1 = require("./utils/transaction");
|
|
5
5
|
const anchor_1 = require("./utils/anchor");
|
|
6
6
|
function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
|
|
7
|
-
const tx = new
|
|
7
|
+
const tx = new transaction_1.Transaction({
|
|
8
8
|
version: 3,
|
|
9
9
|
lockTime: txLocktime,
|
|
10
10
|
});
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SingleKey = void 0;
|
|
4
4
|
const utils_js_1 = require("@scure/btc-signer/utils.js");
|
|
5
|
+
const btc_signer_1 = require("@scure/btc-signer");
|
|
5
6
|
const base_1 = require("@scure/base");
|
|
6
|
-
const transaction_js_1 = require("@scure/btc-signer/transaction.js");
|
|
7
7
|
const signingSession_1 = require("../tree/signingSession");
|
|
8
8
|
const secp256k1_1 = require("@noble/secp256k1");
|
|
9
|
-
const
|
|
10
|
-
const ALL_SIGHASH = Object.values(transaction_js_1.SigHash).filter((x) => typeof x === "number");
|
|
9
|
+
const ALL_SIGHASH = Object.values(btc_signer_1.SigHash).filter((x) => typeof x === "number");
|
|
11
10
|
/**
|
|
12
11
|
* In-memory single key implementation for Bitcoin transaction signing.
|
|
13
12
|
*
|
|
@@ -51,7 +50,7 @@ class SingleKey {
|
|
|
51
50
|
const txCpy = tx.clone();
|
|
52
51
|
if (!inputIndexes) {
|
|
53
52
|
try {
|
|
54
|
-
if (!txCpy.sign(this.key, ALL_SIGHASH
|
|
53
|
+
if (!txCpy.sign(this.key, ALL_SIGHASH)) {
|
|
55
54
|
throw new Error("Failed to sign transaction");
|
|
56
55
|
}
|
|
57
56
|
}
|
|
@@ -67,7 +66,7 @@ class SingleKey {
|
|
|
67
66
|
return txCpy;
|
|
68
67
|
}
|
|
69
68
|
for (const inputIndex of inputIndexes) {
|
|
70
|
-
if (!txCpy.signIdx(this.key, inputIndex, ALL_SIGHASH
|
|
69
|
+
if (!txCpy.signIdx(this.key, inputIndex, ALL_SIGHASH)) {
|
|
71
70
|
throw new Error(`Failed to sign input #${inputIndex}`);
|
|
72
71
|
}
|
|
73
72
|
}
|
|
@@ -82,9 +81,10 @@ class SingleKey {
|
|
|
82
81
|
signerSession() {
|
|
83
82
|
return signingSession_1.TreeSignerSession.random();
|
|
84
83
|
}
|
|
85
|
-
async signMessage(message) {
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
async signMessage(message, signatureType = "schnorr") {
|
|
85
|
+
if (signatureType === "ecdsa")
|
|
86
|
+
return (0, secp256k1_1.sign)(message, this.key, { prehash: false });
|
|
87
|
+
return secp256k1_1.schnorr.sign(message, this.key);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
exports.SingleKey = SingleKey;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.Intent = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.networks = exports.ArkNote = exports.hasBoardingTxExpired = exports.waitForIncomingFunds = exports.verifyTapscriptSignatures = exports.buildOffchainTx = exports.ConditionWitness = exports.VtxoTaprootTree = exports.VtxoTreeExpiry = exports.CosignerPublicKey = exports.getArkPsbtFields = exports.setArkPsbtField = exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = exports.TapTreeCoder = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.Response = exports.Request = exports.ServiceWorkerWallet = exports.Worker = exports.setupServiceWorker = exports.SettlementEventType = exports.ChainTxType = exports.IndexerTxType = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DefaultVtxo = exports.ArkAddress = exports.RestIndexerProvider = exports.RestArkProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.VtxoManager = exports.Ramps = exports.OnchainWallet = exports.SingleKey = exports.Wallet = void 0;
|
|
4
|
+
exports.maybeArkError = exports.ArkError = void 0;
|
|
5
|
+
const transaction_1 = require("./utils/transaction");
|
|
6
|
+
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.Transaction; } });
|
|
6
7
|
const singleKey_1 = require("./identity/singleKey");
|
|
7
8
|
Object.defineProperty(exports, "SingleKey", { enumerable: true, get: function () { return singleKey_1.SingleKey; } });
|
|
8
9
|
const address_1 = require("./script/address");
|
|
@@ -13,6 +14,7 @@ const default_1 = require("./script/default");
|
|
|
13
14
|
Object.defineProperty(exports, "DefaultVtxo", { enumerable: true, get: function () { return default_1.DefaultVtxo; } });
|
|
14
15
|
const base_1 = require("./script/base");
|
|
15
16
|
Object.defineProperty(exports, "VtxoScript", { enumerable: true, get: function () { return base_1.VtxoScript; } });
|
|
17
|
+
Object.defineProperty(exports, "TapTreeCoder", { enumerable: true, get: function () { return base_1.TapTreeCoder; } });
|
|
16
18
|
const wallet_1 = require("./wallet");
|
|
17
19
|
Object.defineProperty(exports, "TxType", { enumerable: true, get: function () { return wallet_1.TxType; } });
|
|
18
20
|
const wallet_2 = require("./wallet/wallet");
|
|
@@ -22,6 +24,8 @@ const txTree_1 = require("./tree/txTree");
|
|
|
22
24
|
Object.defineProperty(exports, "TxTree", { enumerable: true, get: function () { return txTree_1.TxTree; } });
|
|
23
25
|
const ramps_1 = require("./wallet/ramps");
|
|
24
26
|
Object.defineProperty(exports, "Ramps", { enumerable: true, get: function () { return ramps_1.Ramps; } });
|
|
27
|
+
const vtxo_manager_1 = require("./wallet/vtxo-manager");
|
|
28
|
+
Object.defineProperty(exports, "VtxoManager", { enumerable: true, get: function () { return vtxo_manager_1.VtxoManager; } });
|
|
25
29
|
const wallet_3 = require("./wallet/serviceWorker/wallet");
|
|
26
30
|
Object.defineProperty(exports, "ServiceWorkerWallet", { enumerable: true, get: function () { return wallet_3.ServiceWorkerWallet; } });
|
|
27
31
|
const onchain_1 = require("./wallet/onchain");
|
|
@@ -50,6 +54,7 @@ Object.defineProperty(exports, "MultisigTapscript", { enumerable: true, get: fun
|
|
|
50
54
|
const arkTransaction_1 = require("./utils/arkTransaction");
|
|
51
55
|
Object.defineProperty(exports, "hasBoardingTxExpired", { enumerable: true, get: function () { return arkTransaction_1.hasBoardingTxExpired; } });
|
|
52
56
|
Object.defineProperty(exports, "buildOffchainTx", { enumerable: true, get: function () { return arkTransaction_1.buildOffchainTx; } });
|
|
57
|
+
Object.defineProperty(exports, "verifyTapscriptSignatures", { enumerable: true, get: function () { return arkTransaction_1.verifyTapscriptSignatures; } });
|
|
53
58
|
const unknownFields_1 = require("./utils/unknownFields");
|
|
54
59
|
Object.defineProperty(exports, "VtxoTaprootTree", { enumerable: true, get: function () { return unknownFields_1.VtxoTaprootTree; } });
|
|
55
60
|
Object.defineProperty(exports, "ConditionWitness", { enumerable: true, get: function () { return unknownFields_1.ConditionWitness; } });
|
|
@@ -59,8 +64,8 @@ Object.defineProperty(exports, "ArkPsbtFieldKey", { enumerable: true, get: funct
|
|
|
59
64
|
Object.defineProperty(exports, "ArkPsbtFieldKeyType", { enumerable: true, get: function () { return unknownFields_1.ArkPsbtFieldKeyType; } });
|
|
60
65
|
Object.defineProperty(exports, "CosignerPublicKey", { enumerable: true, get: function () { return unknownFields_1.CosignerPublicKey; } });
|
|
61
66
|
Object.defineProperty(exports, "VtxoTreeExpiry", { enumerable: true, get: function () { return unknownFields_1.VtxoTreeExpiry; } });
|
|
62
|
-
const
|
|
63
|
-
Object.defineProperty(exports, "
|
|
67
|
+
const intent_1 = require("./intent");
|
|
68
|
+
Object.defineProperty(exports, "Intent", { enumerable: true, get: function () { return intent_1.Intent; } });
|
|
64
69
|
const arknote_1 = require("./arknote");
|
|
65
70
|
Object.defineProperty(exports, "ArkNote", { enumerable: true, get: function () { return arknote_1.ArkNote; } });
|
|
66
71
|
const networks_1 = require("./networks");
|
|
@@ -77,3 +82,6 @@ const walletRepository_1 = require("./repositories/walletRepository");
|
|
|
77
82
|
Object.defineProperty(exports, "WalletRepositoryImpl", { enumerable: true, get: function () { return walletRepository_1.WalletRepositoryImpl; } });
|
|
78
83
|
const contractRepository_1 = require("./repositories/contractRepository");
|
|
79
84
|
Object.defineProperty(exports, "ContractRepositoryImpl", { enumerable: true, get: function () { return contractRepository_1.ContractRepositoryImpl; } });
|
|
85
|
+
const errors_1 = require("./providers/errors");
|
|
86
|
+
Object.defineProperty(exports, "ArkError", { enumerable: true, get: function () { return errors_1.ArkError; } });
|
|
87
|
+
Object.defineProperty(exports, "maybeArkError", { enumerable: true, get: function () { return errors_1.maybeArkError; } });
|
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
const script_js_1 = require("@scure/btc-signer/script.js");
|
|
6
|
-
const transaction_js_1 = require("@scure/btc-signer/transaction.js");
|
|
7
|
-
const script_js_2 = require("@scure/btc-signer/script.js");
|
|
8
|
-
const errors_1 = require("./errors");
|
|
3
|
+
exports.Intent = void 0;
|
|
4
|
+
const btc_signer_1 = require("@scure/btc-signer");
|
|
9
5
|
const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
|
|
10
|
-
const
|
|
6
|
+
const transaction_1 = require("../utils/transaction");
|
|
11
7
|
/**
|
|
12
|
-
*
|
|
8
|
+
* Intent proof implementation for Bitcoin message signing.
|
|
13
9
|
*
|
|
14
|
-
*
|
|
10
|
+
* Intent proof defines a standard for signing Bitcoin messages as well as proving
|
|
15
11
|
* ownership of coins. This namespace provides utilities for creating and
|
|
16
|
-
* validating
|
|
12
|
+
* validating Intent proof.
|
|
17
13
|
*
|
|
14
|
+
* it is greatly inspired by BIP322.
|
|
18
15
|
* @see https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
|
|
19
16
|
*
|
|
20
17
|
* @example
|
|
21
18
|
* ```typescript
|
|
22
|
-
* // Create a
|
|
23
|
-
* const proof =
|
|
19
|
+
* // Create a Intent proof
|
|
20
|
+
* const proof = Intent.create(
|
|
24
21
|
* "Hello Bitcoin!",
|
|
25
22
|
* [input],
|
|
26
23
|
* [output]
|
|
@@ -29,65 +26,46 @@ const base_1 = require("@scure/base");
|
|
|
29
26
|
* // Sign the proof
|
|
30
27
|
* const signedProof = await identity.sign(proof);
|
|
31
28
|
*
|
|
32
|
-
* // Extract the signature
|
|
33
|
-
* const signature = BIP322.signature(signedProof);
|
|
34
|
-
* ```
|
|
35
29
|
*/
|
|
36
|
-
var
|
|
37
|
-
(function (
|
|
30
|
+
var Intent;
|
|
31
|
+
(function (Intent) {
|
|
38
32
|
/**
|
|
39
|
-
* Creates a new
|
|
33
|
+
* Creates a new Intent proof unsigned transaction.
|
|
40
34
|
*
|
|
41
35
|
* This function constructs a special transaction that can be signed to prove
|
|
42
36
|
* ownership of VTXOs and UTXOs. The proof includes the message to be
|
|
43
37
|
* signed and the inputs/outputs that demonstrate ownership.
|
|
44
38
|
*
|
|
45
|
-
* @param message - The
|
|
39
|
+
* @param message - The Intent message to be signed
|
|
46
40
|
* @param inputs - Array of transaction inputs to prove ownership of
|
|
47
41
|
* @param outputs - Optional array of transaction outputs
|
|
48
|
-
* @returns An unsigned
|
|
42
|
+
* @returns An unsigned Intent proof transaction
|
|
49
43
|
*/
|
|
50
44
|
function create(message, inputs, outputs = []) {
|
|
51
45
|
if (inputs.length == 0)
|
|
52
|
-
throw
|
|
46
|
+
throw new Error("intent proof requires at least one input");
|
|
53
47
|
if (!validateInputs(inputs))
|
|
54
|
-
throw
|
|
48
|
+
throw new Error("invalid inputs");
|
|
55
49
|
if (!validateOutputs(outputs))
|
|
56
|
-
throw
|
|
50
|
+
throw new Error("invalid outputs");
|
|
57
51
|
// create the initial transaction to spend
|
|
58
52
|
const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
|
|
59
53
|
// create the transaction to sign
|
|
60
54
|
return craftToSignTx(toSpend, inputs, outputs);
|
|
61
55
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*
|
|
66
|
-
* This function takes a signed proof transaction and converts it into a
|
|
67
|
-
* base64-encoded signature string. If the proof's inputs have special
|
|
68
|
-
* spending conditions, a custom finalizer can be provided.
|
|
69
|
-
*
|
|
70
|
-
* @param signedProof - The signed BIP-322 proof transaction
|
|
71
|
-
* @param finalizer - Optional custom finalizer function
|
|
72
|
-
* @returns Base64-encoded BIP-322 signature
|
|
73
|
-
*/
|
|
74
|
-
function signature(signedProof, finalizer = (tx) => tx.finalize()) {
|
|
75
|
-
finalizer(signedProof);
|
|
76
|
-
return base_1.base64.encode(signedProof.extract());
|
|
77
|
-
}
|
|
78
|
-
BIP322.signature = signature;
|
|
79
|
-
})(BIP322 || (exports.BIP322 = BIP322 = {}));
|
|
80
|
-
const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([script_js_1.OP.RETURN]);
|
|
56
|
+
Intent.create = create;
|
|
57
|
+
})(Intent || (exports.Intent = Intent = {}));
|
|
58
|
+
const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([btc_signer_1.OP.RETURN]);
|
|
81
59
|
const ZERO_32 = new Uint8Array(32).fill(0);
|
|
82
60
|
const MAX_INDEX = 0xffffffff;
|
|
83
|
-
const
|
|
61
|
+
const TAG_INTENT_PROOF = "ark-intent-proof-message";
|
|
84
62
|
function validateInput(input) {
|
|
85
63
|
if (input.index === undefined)
|
|
86
|
-
throw
|
|
64
|
+
throw new Error("intent proof input requires index");
|
|
87
65
|
if (input.txid === undefined)
|
|
88
|
-
throw
|
|
66
|
+
throw new Error("intent proof input requires txid");
|
|
89
67
|
if (input.witnessUtxo === undefined)
|
|
90
|
-
throw
|
|
68
|
+
throw new Error("intent proof input requires witness utxo");
|
|
91
69
|
return true;
|
|
92
70
|
}
|
|
93
71
|
function validateInputs(inputs) {
|
|
@@ -96,9 +74,9 @@ function validateInputs(inputs) {
|
|
|
96
74
|
}
|
|
97
75
|
function validateOutput(output) {
|
|
98
76
|
if (output.amount === undefined)
|
|
99
|
-
throw
|
|
77
|
+
throw new Error("intent proof output requires amount");
|
|
100
78
|
if (output.script === undefined)
|
|
101
|
-
throw
|
|
79
|
+
throw new Error("intent proof output requires script");
|
|
102
80
|
return true;
|
|
103
81
|
}
|
|
104
82
|
function validateOutputs(outputs) {
|
|
@@ -108,11 +86,8 @@ function validateOutputs(outputs) {
|
|
|
108
86
|
// craftToSpendTx creates the initial transaction that will be spent in the proof
|
|
109
87
|
function craftToSpendTx(message, pkScript) {
|
|
110
88
|
const messageHash = hashMessage(message);
|
|
111
|
-
const tx = new
|
|
89
|
+
const tx = new transaction_1.Transaction({
|
|
112
90
|
version: 0,
|
|
113
|
-
allowUnknownOutputs: true,
|
|
114
|
-
allowUnknown: true,
|
|
115
|
-
allowUnknownInputs: true,
|
|
116
91
|
});
|
|
117
92
|
// add input with zero hash and max index
|
|
118
93
|
tx.addInput({
|
|
@@ -126,18 +101,15 @@ function craftToSpendTx(message, pkScript) {
|
|
|
126
101
|
script: pkScript,
|
|
127
102
|
});
|
|
128
103
|
tx.updateInput(0, {
|
|
129
|
-
finalScriptSig:
|
|
104
|
+
finalScriptSig: btc_signer_1.Script.encode(["OP_0", messageHash]),
|
|
130
105
|
});
|
|
131
106
|
return tx;
|
|
132
107
|
}
|
|
133
108
|
// craftToSignTx creates the transaction that will be signed for the proof
|
|
134
109
|
function craftToSignTx(toSpend, inputs, outputs) {
|
|
135
110
|
const firstInput = inputs[0];
|
|
136
|
-
const tx = new
|
|
111
|
+
const tx = new transaction_1.Transaction({
|
|
137
112
|
version: 2,
|
|
138
|
-
allowUnknownOutputs: outputs.length === 0,
|
|
139
|
-
allowUnknown: true,
|
|
140
|
-
allowUnknownInputs: true,
|
|
141
113
|
lockTime: 0,
|
|
142
114
|
});
|
|
143
115
|
// add the first "toSpend" input
|
|
@@ -149,14 +121,19 @@ function craftToSignTx(toSpend, inputs, outputs) {
|
|
|
149
121
|
script: firstInput.witnessUtxo.script,
|
|
150
122
|
amount: 0n,
|
|
151
123
|
},
|
|
152
|
-
sighashType:
|
|
124
|
+
sighashType: btc_signer_1.SigHash.ALL,
|
|
153
125
|
});
|
|
154
126
|
// add other inputs
|
|
155
|
-
for (const input of inputs) {
|
|
127
|
+
for (const [i, input] of inputs.entries()) {
|
|
156
128
|
tx.addInput({
|
|
157
129
|
...input,
|
|
158
|
-
sighashType:
|
|
130
|
+
sighashType: btc_signer_1.SigHash.ALL,
|
|
159
131
|
});
|
|
132
|
+
if (input.unknown?.length) {
|
|
133
|
+
tx.updateInput(i + 1, {
|
|
134
|
+
unknown: input.unknown,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
160
137
|
}
|
|
161
138
|
// add the special OP_RETURN output if no outputs are provided
|
|
162
139
|
if (outputs.length === 0) {
|
|
@@ -176,5 +153,5 @@ function craftToSignTx(toSpend, inputs, outputs) {
|
|
|
176
153
|
return tx;
|
|
177
154
|
}
|
|
178
155
|
function hashMessage(message) {
|
|
179
|
-
return secp256k1_js_1.schnorr.utils.taggedHash(
|
|
156
|
+
return secp256k1_js_1.schnorr.utils.taggedHash(TAG_INTENT_PROOF, new TextEncoder().encode(message));
|
|
180
157
|
}
|
package/dist/cjs/musig2/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.aggregateKeys = exports.sign = exports.PartialSig = exports.generateNonces = void 0;
|
|
3
|
+
exports.aggregateKeys = exports.sign = exports.PartialSig = exports.aggregateNonces = exports.generateNonces = void 0;
|
|
4
4
|
var nonces_1 = require("./nonces");
|
|
5
5
|
Object.defineProperty(exports, "generateNonces", { enumerable: true, get: function () { return nonces_1.generateNonces; } });
|
|
6
|
+
Object.defineProperty(exports, "aggregateNonces", { enumerable: true, get: function () { return nonces_1.aggregateNonces; } });
|
|
6
7
|
var sign_1 = require("./sign");
|
|
7
8
|
Object.defineProperty(exports, "PartialSig", { enumerable: true, get: function () { return sign_1.PartialSig; } });
|
|
8
9
|
Object.defineProperty(exports, "sign", { enumerable: true, get: function () { return sign_1.sign; } });
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateNonces = generateNonces;
|
|
37
|
+
exports.aggregateNonces = aggregateNonces;
|
|
37
38
|
const musig = __importStar(require("@scure/btc-signer/musig2.js"));
|
|
38
39
|
/**
|
|
39
40
|
* Generates a pair of public and secret nonces for MuSig2 signing
|
|
@@ -42,3 +43,6 @@ function generateNonces(publicKey) {
|
|
|
42
43
|
const nonces = musig.nonceGen(publicKey);
|
|
43
44
|
return { secNonce: nonces.secret, pubNonce: nonces.public };
|
|
44
45
|
}
|
|
46
|
+
function aggregateNonces(pubNonces) {
|
|
47
|
+
return musig.nonceAggregate(pubNonces);
|
|
48
|
+
}
|