@bsv/sdk 1.1.32 → 1.2.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/dist/cjs/mod.js +4 -0
- package/dist/cjs/mod.js.map +1 -1
- package/dist/cjs/package.json +4 -3
- package/dist/cjs/src/auth/Certificate.js +163 -0
- package/dist/cjs/src/auth/Certificate.js.map +1 -0
- package/dist/cjs/src/auth/index.js +9 -0
- package/dist/cjs/src/auth/index.js.map +1 -0
- package/dist/cjs/src/compat/BSM.js +17 -7
- package/dist/cjs/src/compat/BSM.js.map +1 -1
- package/dist/cjs/src/compat/ECIES.js +17 -7
- package/dist/cjs/src/compat/ECIES.js.map +1 -1
- package/dist/cjs/src/compat/HD.js +17 -7
- package/dist/cjs/src/compat/HD.js.map +1 -1
- package/dist/cjs/src/compat/Mnemonic.js +17 -7
- package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
- package/dist/cjs/src/compat/index.js +17 -7
- package/dist/cjs/src/compat/index.js.map +1 -1
- package/dist/cjs/src/messages/index.js +17 -7
- package/dist/cjs/src/messages/index.js.map +1 -1
- package/dist/cjs/src/overlay-tools/LookupResolver.js +170 -0
- package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -0
- package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js +69 -0
- package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -0
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +336 -0
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -0
- package/dist/cjs/src/overlay-tools/index.js +29 -0
- package/dist/cjs/src/overlay-tools/index.js.map +1 -0
- package/dist/cjs/src/primitives/PrivateKey.js +17 -7
- package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js +17 -7
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/index.js +17 -7
- package/dist/cjs/src/primitives/index.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +17 -7
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/script/templates/PushDrop.js +218 -0
- package/dist/cjs/src/script/templates/PushDrop.js.map +1 -0
- package/dist/cjs/src/script/templates/index.js +3 -1
- package/dist/cjs/src/script/templates/index.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +35 -6
- package/dist/cjs/src/transaction/Beef.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +13 -4
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js +1 -1
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/cjs/src/wallet/CachedKeyDeriver.js +177 -0
- package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -0
- package/dist/cjs/src/wallet/KeyDeriver.js +174 -0
- package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -0
- package/dist/cjs/src/wallet/ProtoWallet.js +245 -0
- package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -0
- package/dist/cjs/src/wallet/Wallet.interfaces.js +3 -0
- package/dist/cjs/src/wallet/Wallet.interfaces.js.map +1 -0
- package/dist/cjs/src/wallet/WalletClient.js +181 -0
- package/dist/cjs/src/wallet/WalletClient.js.map +1 -0
- package/dist/cjs/src/wallet/WalletError.js +28 -0
- package/dist/cjs/src/wallet/WalletError.js.map +1 -0
- package/dist/cjs/src/wallet/index.js +34 -0
- package/dist/cjs/src/wallet/index.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +45 -0
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/WalletWire.js +3 -0
- package/dist/cjs/src/wallet/substrates/WalletWire.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/WalletWireCalls.js +36 -0
- package/dist/cjs/src/wallet/substrates/WalletWireCalls.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +1821 -0
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +1305 -0
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/XDM.js +130 -0
- package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/index.js +33 -0
- package/dist/cjs/src/wallet/substrates/index.js.map +1 -0
- package/dist/cjs/src/wallet/substrates/window.CWI.js +102 -0
- package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/mod.js +4 -0
- package/dist/esm/mod.js.map +1 -1
- package/dist/esm/src/auth/Certificate.js +185 -0
- package/dist/esm/src/auth/Certificate.js.map +1 -0
- package/dist/esm/src/auth/index.js +2 -0
- package/dist/esm/src/auth/index.js.map +1 -0
- package/dist/esm/src/overlay-tools/LookupResolver.js +167 -0
- package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -0
- package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js +64 -0
- package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -0
- package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +335 -0
- package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -0
- package/dist/esm/src/overlay-tools/index.js +6 -0
- package/dist/esm/src/overlay-tools/index.js.map +1 -0
- package/dist/esm/src/script/templates/PushDrop.js +215 -0
- package/dist/esm/src/script/templates/PushDrop.js.map +1 -0
- package/dist/esm/src/script/templates/index.js +1 -0
- package/dist/esm/src/script/templates/index.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +35 -6
- package/dist/esm/src/transaction/Beef.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +13 -4
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/http/DefaultHttpClient.js +1 -1
- package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/esm/src/wallet/CachedKeyDeriver.js +174 -0
- package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -0
- package/dist/esm/src/wallet/KeyDeriver.js +172 -0
- package/dist/esm/src/wallet/KeyDeriver.js.map +1 -0
- package/dist/esm/src/wallet/ProtoWallet.js +207 -0
- package/dist/esm/src/wallet/ProtoWallet.js.map +1 -0
- package/dist/esm/src/wallet/Wallet.interfaces.js +2 -0
- package/dist/esm/src/wallet/Wallet.interfaces.js.map +1 -0
- package/dist/esm/src/wallet/WalletClient.js +177 -0
- package/dist/esm/src/wallet/WalletClient.js.map +1 -0
- package/dist/esm/src/wallet/WalletError.js +25 -0
- package/dist/esm/src/wallet/WalletError.js.map +1 -0
- package/dist/esm/src/wallet/index.js +9 -0
- package/dist/esm/src/wallet/index.js.map +1 -0
- package/dist/esm/src/wallet/substrates/HTTPWalletWire.js +42 -0
- package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -0
- package/dist/esm/src/wallet/substrates/WalletWire.js +2 -0
- package/dist/esm/src/wallet/substrates/WalletWire.js.map +1 -0
- package/dist/esm/src/wallet/substrates/WalletWireCalls.js +34 -0
- package/dist/esm/src/wallet/substrates/WalletWireCalls.js.map +1 -0
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1816 -0
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -0
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +1300 -0
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -0
- package/dist/esm/src/wallet/substrates/XDM.js +128 -0
- package/dist/esm/src/wallet/substrates/XDM.js.map +1 -0
- package/dist/esm/src/wallet/substrates/index.js +8 -0
- package/dist/esm/src/wallet/substrates/index.js.map +1 -0
- package/dist/esm/src/wallet/substrates/window.CWI.js +100 -0
- package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/mod.d.ts +4 -0
- package/dist/types/mod.d.ts.map +1 -1
- package/dist/types/src/auth/Certificate.d.ts +76 -0
- package/dist/types/src/auth/Certificate.d.ts.map +1 -0
- package/dist/types/src/auth/index.d.ts +2 -0
- package/dist/types/src/auth/index.d.ts.map +1 -0
- package/dist/types/src/overlay-tools/LookupResolver.d.ts +71 -0
- package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -0
- package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts +44 -0
- package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts.map +1 -0
- package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts +90 -0
- package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -0
- package/dist/types/src/overlay-tools/index.d.ts +6 -0
- package/dist/types/src/overlay-tools/index.d.ts.map +1 -0
- package/dist/types/src/script/templates/PushDrop.d.ts +53 -0
- package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -0
- package/dist/types/src/script/templates/index.d.ts +1 -0
- package/dist/types/src/script/templates/index.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +16 -1
- package/dist/types/src/transaction/Beef.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/src/wallet/CachedKeyDeriver.d.ts +92 -0
- package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -0
- package/dist/types/src/wallet/KeyDeriver.d.ts +72 -0
- package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -0
- package/dist/types/src/wallet/ProtoWallet.d.ts +415 -0
- package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -0
- package/dist/types/src/wallet/Wallet.interfaces.d.ts +996 -0
- package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -0
- package/dist/types/src/wallet/WalletClient.d.ts +182 -0
- package/dist/types/src/wallet/WalletClient.d.ts.map +1 -0
- package/dist/types/src/wallet/WalletError.d.ts +14 -0
- package/dist/types/src/wallet/WalletError.d.ts.map +1 -0
- package/dist/types/src/wallet/index.d.ts +9 -0
- package/dist/types/src/wallet/index.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/HTTPWalletWire.d.ts +9 -0
- package/dist/types/src/wallet/substrates/HTTPWalletWire.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/WalletWire.d.ts +7 -0
- package/dist/types/src/wallet/substrates/WalletWire.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/WalletWireCalls.d.ts +33 -0
- package/dist/types/src/wallet/substrates/WalletWireCalls.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts +18 -0
- package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts +196 -0
- package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/XDM.d.ts +412 -0
- package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/index.d.ts +8 -0
- package/dist/types/src/wallet/substrates/index.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/window.CWI.d.ts +410 -0
- package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/overlay-tools.md +551 -0
- package/docs/script.md +135 -0
- package/docs/totp.md +119 -0
- package/docs/transaction.md +25 -0
- package/docs/wallet-substrates.md +10 -0
- package/docs/wallet.md +4182 -0
- package/mod.ts +5 -1
- package/package.json +44 -3
- package/src/auth/Certificate.ts +233 -0
- package/src/auth/__tests/Certificate.test.ts +282 -0
- package/src/auth/index.ts +1 -0
- package/src/overlay-tools/LookupResolver.ts +228 -0
- package/src/overlay-tools/OverlayAdminTokenTemplate.ts +79 -0
- package/src/overlay-tools/SHIPBroadcaster.ts +405 -0
- package/src/overlay-tools/__tests/LookupResolver.test.ts +1403 -0
- package/src/overlay-tools/__tests/OverlayAdminTokenTemplate.test.ts +69 -0
- package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +904 -0
- package/src/overlay-tools/index.ts +5 -0
- package/src/script/templates/PushDrop.ts +246 -0
- package/src/script/templates/__tests/PushDrop.test.ts +158 -0
- package/src/script/templates/index.ts +1 -0
- package/src/transaction/Beef.ts +36 -6
- package/src/transaction/Transaction.ts +13 -4
- package/src/transaction/__tests/Beef.test.ts +20 -6
- package/src/transaction/http/DefaultHttpClient.ts +1 -1
- package/src/wallet/CachedKeyDeriver.ts +193 -0
- package/src/wallet/KeyDeriver.ts +178 -0
- package/src/wallet/ProtoWallet.ts +732 -0
- package/src/wallet/Wallet.interfaces.ts +1170 -0
- package/src/wallet/WalletClient.ts +201 -0
- package/src/wallet/WalletError.ts +27 -0
- package/src/wallet/__tests/CachedKeyDeriver.test.ts +322 -0
- package/src/wallet/__tests/KeyDeriver.test.ts +118 -0
- package/src/wallet/__tests/ProtoWallet.test.ts +543 -0
- package/src/wallet/index.ts +8 -0
- package/src/wallet/substrates/HTTPWalletWire.ts +47 -0
- package/src/wallet/substrates/WalletWire.ts +6 -0
- package/src/wallet/substrates/WalletWireCalls.ts +34 -0
- package/src/wallet/substrates/WalletWireProcessor.ts +2046 -0
- package/src/wallet/substrates/WalletWireTransceiver.ts +1454 -0
- package/src/wallet/substrates/XDM.ts +157 -0
- package/src/wallet/substrates/__tests/WalletWire.integration.test.ts +2194 -0
- package/src/wallet/substrates/__tests/XDM.test.ts +659 -0
- package/src/wallet/substrates/index.ts +7 -0
- package/src/wallet/substrates/window.CWI.ts +133 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './LookupResolver.js'
|
|
2
|
+
export * from './SHIPBroadcaster.js'
|
|
3
|
+
export { default as OverlayAdminTokenTemplate } from './OverlayAdminTokenTemplate.js'
|
|
4
|
+
export { default as LookupResolver } from './LookupResolver.js'
|
|
5
|
+
export { default as SHIPBroadcaster } from './SHIPBroadcaster.js'
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { ScriptTemplate, LockingScript, UnlockingScript, OP } from '../index.js'
|
|
2
|
+
import { Utils, Hash, TransactionSignature, Signature, PublicKey } from '../../primitives/index.js'
|
|
3
|
+
import { Wallet } from '../../wallet/Wallet.interfaces.js'
|
|
4
|
+
import { Transaction } from '../../transaction/index.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* For a given piece of data to push onto the stack in script, creates the correct minimally-encoded script chunk,
|
|
8
|
+
* including the correct push operation.
|
|
9
|
+
*
|
|
10
|
+
* TODO: This should be made into a TS-SDK util (distinct from the `minimallyEncode` util)
|
|
11
|
+
*/
|
|
12
|
+
const createMinimallyEncodedScriptChunk = (data: number[]): { op: number, data?: number[] } => {
|
|
13
|
+
if (data.length === 0) {
|
|
14
|
+
// Could have used OP_0.
|
|
15
|
+
return { op: 0 }
|
|
16
|
+
}
|
|
17
|
+
if (data.length === 1 && data[0] === 0) {
|
|
18
|
+
// Could have used OP_0.
|
|
19
|
+
return { op: 0 }
|
|
20
|
+
}
|
|
21
|
+
if (data.length === 1 && data[0] > 0 && data[0] <= 16) {
|
|
22
|
+
// Could have used OP_0 .. OP_16.
|
|
23
|
+
return { op: 0x50 + data[0] }
|
|
24
|
+
}
|
|
25
|
+
if (data.length === 1 && data[0] === 0x81) {
|
|
26
|
+
// Could have used OP_1NEGATE.
|
|
27
|
+
return { op: 0x4f }
|
|
28
|
+
}
|
|
29
|
+
if (data.length <= 75) {
|
|
30
|
+
// Could have used a direct push (opcode indicating number of bytes
|
|
31
|
+
// pushed + those bytes).
|
|
32
|
+
return { op: data.length, data }
|
|
33
|
+
}
|
|
34
|
+
if (data.length <= 255) {
|
|
35
|
+
// Could have used OP_PUSHDATA.
|
|
36
|
+
return { op: 0x4c, data }
|
|
37
|
+
}
|
|
38
|
+
if (data.length <= 65535) {
|
|
39
|
+
// Could have used OP_PUSHDATA2.
|
|
40
|
+
return { op: 0x4d, data }
|
|
41
|
+
}
|
|
42
|
+
return { op: 0x4e, data }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default class PushDrop implements ScriptTemplate {
|
|
46
|
+
wallet: Wallet
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Decodes a PushDrop script back into its token fields and the locking public key. If a signature was present, it will be the last field returned.
|
|
50
|
+
* Warning: Only works with a P2PK lock at the beginning of the script.
|
|
51
|
+
* @param script PushDrop script to decode back into token fields
|
|
52
|
+
* @returns An object containing PushDrop token fields and the locking public key. If a signature was included, it will be the last field.
|
|
53
|
+
*/
|
|
54
|
+
static decode(script: LockingScript): { lockingPublicKey: PublicKey, fields: number[][] } {
|
|
55
|
+
const lockingPublicKey = PublicKey.fromString(Utils.toHex(script.chunks[0].data))
|
|
56
|
+
const fields = []
|
|
57
|
+
for (let i = 2; i < script.chunks.length; i++) {
|
|
58
|
+
const nextOpcode = script.chunks[i + 1].op
|
|
59
|
+
let chunk = script.chunks[i].data
|
|
60
|
+
if (!chunk) {
|
|
61
|
+
if (script.chunks[i].op >= 80 && script.chunks[i].op <= 95) {
|
|
62
|
+
chunk = [script.chunks[i].op - 80]
|
|
63
|
+
} else if (script.chunks[i].op === 0) {
|
|
64
|
+
chunk = [0]
|
|
65
|
+
} else if (script.chunks[i].op === 0x4f) {
|
|
66
|
+
chunk = [0x81]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
fields.push(chunk)
|
|
70
|
+
|
|
71
|
+
// If the next value is DROP or 2DROP then this is the final field
|
|
72
|
+
if (nextOpcode === OP.OP_DROP || nextOpcode === OP.OP_2DROP) {
|
|
73
|
+
break
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
fields,
|
|
79
|
+
lockingPublicKey
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Constructs a new instance of the PushDrop class.
|
|
85
|
+
*
|
|
86
|
+
* @param {Wallet} wallet - The wallet interface used for creating signatures and accessing public keys.
|
|
87
|
+
*/
|
|
88
|
+
constructor(wallet: Wallet) {
|
|
89
|
+
this.wallet = wallet
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Creates a PushDrop locking script with arbitrary data fields and a public key lock.
|
|
94
|
+
*
|
|
95
|
+
* @param {number[][]} fields - The token fields to include in the locking script.
|
|
96
|
+
* @param {[0 | 1 | 2, string]} protocolID - The protocol ID to use.
|
|
97
|
+
* @param {string} keyID - The key ID to use.
|
|
98
|
+
* @param {string} counterparty - The counterparty involved in the transaction, "self" or "anyone".
|
|
99
|
+
* @param {boolean} [forSelf=false] - Flag indicating if the lock is for the creator (default no).
|
|
100
|
+
* @param {boolean} [includeSignature=true] - Flag indicating if a signature should be included in the script (default yes).
|
|
101
|
+
* @returns {Promise<LockingScript>} The generated PushDrop locking script.
|
|
102
|
+
*/
|
|
103
|
+
async lock(fields: number[][], protocolID: [0 | 1 | 2, string], keyID: string, counterparty: string, forSelf = false, includeSignature = true, lockPosition: 'before' | 'after' = 'before'): Promise<LockingScript> {
|
|
104
|
+
const { publicKey } = await this.wallet.getPublicKey({
|
|
105
|
+
protocolID,
|
|
106
|
+
keyID,
|
|
107
|
+
counterparty,
|
|
108
|
+
forSelf
|
|
109
|
+
})
|
|
110
|
+
const lockChunks: Array<{ op: number, data?: number[] }> = []
|
|
111
|
+
const pushDropChunks: Array<{ op: number, data?: number[] }> = []
|
|
112
|
+
lockChunks.push({ op: publicKey.length / 2, data: Utils.toArray(publicKey, 'hex') })
|
|
113
|
+
lockChunks.push({ op: OP.OP_CHECKSIG })
|
|
114
|
+
if (includeSignature) {
|
|
115
|
+
const dataToSign = fields.reduce((a, e) => [...a, ...e], [])
|
|
116
|
+
const { signature } = await this.wallet.createSignature({
|
|
117
|
+
data: dataToSign,
|
|
118
|
+
protocolID,
|
|
119
|
+
keyID,
|
|
120
|
+
counterparty
|
|
121
|
+
})
|
|
122
|
+
fields.push(signature)
|
|
123
|
+
}
|
|
124
|
+
for (const field of fields) {
|
|
125
|
+
pushDropChunks.push(createMinimallyEncodedScriptChunk(field))
|
|
126
|
+
}
|
|
127
|
+
let notYetDropped = fields.length
|
|
128
|
+
while (notYetDropped > 1) {
|
|
129
|
+
pushDropChunks.push({ op: OP.OP_2DROP })
|
|
130
|
+
notYetDropped -= 2
|
|
131
|
+
}
|
|
132
|
+
if (notYetDropped) {
|
|
133
|
+
pushDropChunks.push({ op: OP.OP_DROP })
|
|
134
|
+
}
|
|
135
|
+
if (lockPosition === 'before') {
|
|
136
|
+
return new LockingScript([
|
|
137
|
+
...lockChunks,
|
|
138
|
+
...pushDropChunks
|
|
139
|
+
])
|
|
140
|
+
} else {
|
|
141
|
+
return new LockingScript([
|
|
142
|
+
...pushDropChunks,
|
|
143
|
+
...lockChunks
|
|
144
|
+
])
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Creates an unlocking script for spending a PushDrop token output.
|
|
150
|
+
*
|
|
151
|
+
* @param {[0 | 1 | 2, string]} protocolID - The protocol ID to use.
|
|
152
|
+
* @param {string} keyID - The key ID to use.
|
|
153
|
+
* @param {string} counterparty - The counterparty involved in the transaction, "self" or "anyone".
|
|
154
|
+
* @param {string} [sourceTXID] - The TXID of the source transaction.
|
|
155
|
+
* @param {number} [sourceSatoshis] - The number of satoshis in the source output.
|
|
156
|
+
* @param {LockingScript} [lockingScript] - The locking script of the source output.
|
|
157
|
+
* @param {'all' | 'none' | 'single'} [signOutputs='all'] - Specifies which outputs to sign.
|
|
158
|
+
* @param {boolean} [anyoneCanPay=false] - Specifies if the anyone-can-pay flag is set.
|
|
159
|
+
* @returns {Object} An object containing functions to sign the transaction and estimate the script length.
|
|
160
|
+
*/
|
|
161
|
+
unlock(
|
|
162
|
+
protocolID: [0 | 1 | 2, string],
|
|
163
|
+
keyID: string,
|
|
164
|
+
counterparty: string,
|
|
165
|
+
signOutputs: 'all' | 'none' | 'single' = 'all',
|
|
166
|
+
anyoneCanPay = false,
|
|
167
|
+
sourceSatoshis?: number,
|
|
168
|
+
lockingScript?: LockingScript
|
|
169
|
+
): {
|
|
170
|
+
sign: (tx: Transaction, inputIndex: number) => Promise<UnlockingScript>
|
|
171
|
+
estimateLength: () => Promise<73>
|
|
172
|
+
} {
|
|
173
|
+
return {
|
|
174
|
+
sign: async (tx: Transaction, inputIndex: number): Promise<UnlockingScript> => {
|
|
175
|
+
let signatureScope = TransactionSignature.SIGHASH_FORKID
|
|
176
|
+
if (signOutputs === 'all') {
|
|
177
|
+
signatureScope |= TransactionSignature.SIGHASH_ALL
|
|
178
|
+
}
|
|
179
|
+
if (signOutputs === 'none') {
|
|
180
|
+
signatureScope |= TransactionSignature.SIGHASH_NONE
|
|
181
|
+
}
|
|
182
|
+
if (signOutputs === 'single') {
|
|
183
|
+
signatureScope |= TransactionSignature.SIGHASH_SINGLE
|
|
184
|
+
}
|
|
185
|
+
if (anyoneCanPay) {
|
|
186
|
+
signatureScope |= TransactionSignature.SIGHASH_ANYONECANPAY
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const input = tx.inputs[inputIndex]
|
|
190
|
+
|
|
191
|
+
const otherInputs = tx.inputs.filter((_, index) => index !== inputIndex)
|
|
192
|
+
|
|
193
|
+
const sourceTXID = input.sourceTXID ? input.sourceTXID : input.sourceTransaction?.id('hex')
|
|
194
|
+
if (!sourceTXID) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
'The input sourceTXID or sourceTransaction is required for transaction signing.'
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
sourceSatoshis ||= input.sourceTransaction?.outputs[input.sourceOutputIndex].satoshis
|
|
200
|
+
if (!sourceSatoshis) {
|
|
201
|
+
throw new Error(
|
|
202
|
+
'The sourceSatoshis or input sourceTransaction is required for transaction signing.'
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
lockingScript ||= input.sourceTransaction?.outputs[input.sourceOutputIndex].lockingScript
|
|
206
|
+
if (!lockingScript) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
'The lockingScript or input sourceTransaction is required for transaction signing.'
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const preimage = TransactionSignature.format({
|
|
213
|
+
sourceTXID,
|
|
214
|
+
sourceOutputIndex: input.sourceOutputIndex,
|
|
215
|
+
sourceSatoshis,
|
|
216
|
+
transactionVersion: tx.version,
|
|
217
|
+
otherInputs,
|
|
218
|
+
inputIndex,
|
|
219
|
+
outputs: tx.outputs,
|
|
220
|
+
inputSequence: input.sequence,
|
|
221
|
+
subscript: lockingScript,
|
|
222
|
+
lockTime: tx.lockTime,
|
|
223
|
+
scope: signatureScope
|
|
224
|
+
})
|
|
225
|
+
const preimageHash = Hash.sha256(preimage)
|
|
226
|
+
const { signature: bareSignature } = await this.wallet.createSignature({
|
|
227
|
+
data: preimageHash,
|
|
228
|
+
protocolID,
|
|
229
|
+
keyID,
|
|
230
|
+
counterparty
|
|
231
|
+
})
|
|
232
|
+
const signature = Signature.fromDER([...bareSignature])
|
|
233
|
+
const txSignature = new TransactionSignature(
|
|
234
|
+
signature.r,
|
|
235
|
+
signature.s,
|
|
236
|
+
signatureScope
|
|
237
|
+
)
|
|
238
|
+
const sigForScript = txSignature.toChecksigFormat()
|
|
239
|
+
return new UnlockingScript([
|
|
240
|
+
{ op: sigForScript.length, data: sigForScript }
|
|
241
|
+
])
|
|
242
|
+
},
|
|
243
|
+
estimateLength: async () => 73
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/* eslint-env jest */
|
|
2
|
+
import PushDrop from '../../../../dist/cjs/src/script/templates/PushDrop.js'
|
|
3
|
+
import ProtoWallet from '../../../../dist/cjs/src/wallet/ProtoWallet.js'
|
|
4
|
+
import { PrivateKey, Utils } from '../../../../dist/cjs/src/primitives/index.js'
|
|
5
|
+
import { Script, Spend } from '../../../../dist/cjs/src/script/index.js'
|
|
6
|
+
import { Transaction } from '../../../../dist/cjs/src/transaction/index.js'
|
|
7
|
+
|
|
8
|
+
describe('PushDrop', () => {
|
|
9
|
+
let privateKey: typeof PrivateKey
|
|
10
|
+
let wallet
|
|
11
|
+
let pushDrop: PushDrop
|
|
12
|
+
|
|
13
|
+
const createDecodeRedeem = async (fields: number[][] = [], protocolID: [0 | 1 | 2, string] = [0, 'tests'], keyID: string = 'test-key', counterparty: string = 'self', signOutputs: 'all' | 'none' | 'single' = 'all', anyoneCanPay: boolean = false) => {
|
|
14
|
+
const lockingScript = await pushDrop.lock(fields, protocolID, keyID, counterparty)
|
|
15
|
+
expect(lockingScript).toBeInstanceOf(Script)
|
|
16
|
+
const decoded = await PushDrop.decode(lockingScript)
|
|
17
|
+
expect(decoded.fields).toEqual(fields)
|
|
18
|
+
const expectedPublicKey = (await wallet.getPublicKey({ protocolID, keyID, counterparty })).publicKey
|
|
19
|
+
expect(decoded.lockingPublicKey.toString()).toEqual(expectedPublicKey)
|
|
20
|
+
const satoshis = 1
|
|
21
|
+
const unlockingTemplate = await pushDrop.unlock(protocolID, keyID, counterparty, signOutputs, anyoneCanPay)
|
|
22
|
+
const sourceTx = new Transaction(1, [], [{
|
|
23
|
+
lockingScript,
|
|
24
|
+
satoshis
|
|
25
|
+
}], 0)
|
|
26
|
+
const spendTx = new Transaction(1, [{
|
|
27
|
+
sourceTransaction: sourceTx,
|
|
28
|
+
sourceOutputIndex: 0,
|
|
29
|
+
sequence: 0xffffffff
|
|
30
|
+
}], [], 0)
|
|
31
|
+
const unlockingScript = await unlockingTemplate.sign(spendTx, 0)
|
|
32
|
+
expect(await unlockingTemplate.estimateLength()).toEqual(73)
|
|
33
|
+
const spend = new Spend({
|
|
34
|
+
sourceTXID: sourceTx.id('hex'),
|
|
35
|
+
sourceOutputIndex: 0,
|
|
36
|
+
sourceSatoshis: satoshis,
|
|
37
|
+
lockingScript,
|
|
38
|
+
transactionVersion: 1,
|
|
39
|
+
otherInputs: [],
|
|
40
|
+
inputIndex: 0,
|
|
41
|
+
unlockingScript,
|
|
42
|
+
outputs: [],
|
|
43
|
+
inputSequence: 0xffffffff,
|
|
44
|
+
lockTime: 0
|
|
45
|
+
})
|
|
46
|
+
const valid = spend.validate()
|
|
47
|
+
expect(valid).toBe(true)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
privateKey = PrivateKey.fromRandom()
|
|
52
|
+
wallet = new ProtoWallet(privateKey)
|
|
53
|
+
pushDrop = new PushDrop(wallet)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('Passes various test vectors', async () => {
|
|
57
|
+
await createDecodeRedeem()
|
|
58
|
+
await createDecodeRedeem([[0]])
|
|
59
|
+
await createDecodeRedeem([[1]])
|
|
60
|
+
await createDecodeRedeem([[0x81]])
|
|
61
|
+
await createDecodeRedeem([[3, 1, 4, 1, 5, 9]])
|
|
62
|
+
await createDecodeRedeem([new Array(200).fill(0xff)])
|
|
63
|
+
await createDecodeRedeem([new Array(400).fill(0xff)])
|
|
64
|
+
await createDecodeRedeem([new Array(70000).fill(0xff)])
|
|
65
|
+
await createDecodeRedeem([[0], [1], [2]])
|
|
66
|
+
await createDecodeRedeem([[0], [1], [2], [3]])
|
|
67
|
+
await createDecodeRedeem([[3, 1, 4, 1, 5, 9]], undefined, undefined, undefined, 'none', false)
|
|
68
|
+
await createDecodeRedeem([[3, 1, 4, 1, 5, 9]], undefined, undefined, undefined, 'single', false)
|
|
69
|
+
await createDecodeRedeem([[3, 1, 4, 1, 5, 9]], undefined, undefined, undefined, 'all', true)
|
|
70
|
+
await createDecodeRedeem([[3, 1, 4, 1, 5, 9]], undefined, undefined, undefined, 'none', true)
|
|
71
|
+
await createDecodeRedeem([[3, 1, 4, 1, 5, 9]], undefined, undefined, undefined, 'single', true)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('lock', () => {
|
|
75
|
+
it('creates a correct locking script', async () => {
|
|
76
|
+
const fields = [
|
|
77
|
+
Utils.toArray('hello world', 'utf8'),
|
|
78
|
+
Utils.toArray('This is a field', 'utf8'),
|
|
79
|
+
[0xde, 0xad, 0xbe, 0xef]
|
|
80
|
+
]
|
|
81
|
+
const protocolID: [0 | 1 | 2, string] = [0, 'tests']
|
|
82
|
+
const keyID = 'test-key'
|
|
83
|
+
const counterparty = 'self'
|
|
84
|
+
const lockingScript = await pushDrop.lock(fields, protocolID, keyID, counterparty)
|
|
85
|
+
|
|
86
|
+
// Check that the locking script is not null
|
|
87
|
+
expect(lockingScript).toBeInstanceOf(Script)
|
|
88
|
+
|
|
89
|
+
// Decode the locking script and check the fields and locking public key
|
|
90
|
+
const decoded = await PushDrop.decode(lockingScript)
|
|
91
|
+
expect(decoded.fields).toEqual(fields)
|
|
92
|
+
const expectedPublicKey = (await wallet.getPublicKey({ protocolID, keyID, counterparty })).publicKey
|
|
93
|
+
expect(decoded.lockingPublicKey.toString()).toEqual(expectedPublicKey)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('unlock', () => {
|
|
98
|
+
it('creates a correct unlocking script', async () => {
|
|
99
|
+
const fields = [
|
|
100
|
+
Utils.toArray('hello world', 'utf8'),
|
|
101
|
+
Utils.toArray('This is a field', 'utf8'),
|
|
102
|
+
[0xde, 0xad, 0xbe, 0xef]
|
|
103
|
+
]
|
|
104
|
+
const protocolID: [0 | 1 | 2, string] = [0, 'tests']
|
|
105
|
+
const keyID = 'test-key'
|
|
106
|
+
const counterparty = 'self'
|
|
107
|
+
const lockingScript = await pushDrop.lock(fields, protocolID, keyID, counterparty)
|
|
108
|
+
const satoshis = 1
|
|
109
|
+
const unlockingTemplate = await pushDrop.unlock(protocolID, keyID, counterparty)
|
|
110
|
+
const sourceTx = new Transaction(1, [], [{
|
|
111
|
+
lockingScript,
|
|
112
|
+
satoshis
|
|
113
|
+
}], 0)
|
|
114
|
+
const spendTx = new Transaction(1, [{
|
|
115
|
+
sourceTransaction: sourceTx,
|
|
116
|
+
sourceOutputIndex: 0,
|
|
117
|
+
sequence: 0xffffffff
|
|
118
|
+
}], [], 0)
|
|
119
|
+
const unlockingScript = await unlockingTemplate.sign(spendTx, 0)
|
|
120
|
+
expect(await unlockingTemplate.estimateLength()).toEqual(73)
|
|
121
|
+
const spend = new Spend({
|
|
122
|
+
sourceTXID: sourceTx.id('hex'),
|
|
123
|
+
sourceOutputIndex: 0,
|
|
124
|
+
sourceSatoshis: satoshis,
|
|
125
|
+
lockingScript,
|
|
126
|
+
transactionVersion: 1,
|
|
127
|
+
otherInputs: [],
|
|
128
|
+
inputIndex: 0,
|
|
129
|
+
unlockingScript,
|
|
130
|
+
outputs: [],
|
|
131
|
+
inputSequence: 0xffffffff,
|
|
132
|
+
lockTime: 0
|
|
133
|
+
})
|
|
134
|
+
const valid = spend.validate()
|
|
135
|
+
expect(valid).toBe(true)
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe('decode', () => {
|
|
140
|
+
it('decodes the locking script correctly', async () => {
|
|
141
|
+
const fields = [
|
|
142
|
+
Utils.toArray('hello world', 'utf8'),
|
|
143
|
+
Utils.toArray('This is a field', 'utf8'),
|
|
144
|
+
[0xde, 0xad, 0xbe, 0xef]
|
|
145
|
+
]
|
|
146
|
+
const protocolID: [0 | 1 | 2, string] = [0, 'tests']
|
|
147
|
+
const keyID = 'test-key'
|
|
148
|
+
const counterparty = 'self'
|
|
149
|
+
|
|
150
|
+
const lockingScript = await pushDrop.lock(fields, protocolID, keyID, counterparty)
|
|
151
|
+
|
|
152
|
+
const decoded = await PushDrop.decode(lockingScript)
|
|
153
|
+
expect(decoded.fields).toEqual(fields)
|
|
154
|
+
const expectedPublicKey = (await wallet.getPublicKey({ protocolID, keyID, counterparty })).publicKey
|
|
155
|
+
expect(decoded.lockingPublicKey.toString()).toEqual(expectedPublicKey)
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
})
|
package/src/transaction/Beef.ts
CHANGED
|
@@ -396,11 +396,10 @@ export class Beef {
|
|
|
396
396
|
}
|
|
397
397
|
|
|
398
398
|
/**
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const writer = new Writer()
|
|
399
|
+
* Serializes this data to `writer`
|
|
400
|
+
* @param writer
|
|
401
|
+
*/
|
|
402
|
+
toWriter (writer: Writer) {
|
|
404
403
|
writer.writeUInt32LE(this.magic)
|
|
405
404
|
|
|
406
405
|
writer.writeVarIntNum(this.bumps.length)
|
|
@@ -412,7 +411,38 @@ export class Beef {
|
|
|
412
411
|
for (const tx of this.txs) {
|
|
413
412
|
tx.toWriter(writer, this.magic)
|
|
414
413
|
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Returns a binary array representing the serialized BEEF
|
|
418
|
+
* @returns A binary array representing the BEEF
|
|
419
|
+
*/
|
|
420
|
+
toBinary (): number[] {
|
|
421
|
+
const writer = new Writer()
|
|
422
|
+
this.toWriter(writer)
|
|
423
|
+
return writer.toArray()
|
|
424
|
+
}
|
|
415
425
|
|
|
426
|
+
/**
|
|
427
|
+
* Serialize this Beef as AtomicBEEF.
|
|
428
|
+
*
|
|
429
|
+
* `txid` must exist and be the last transaction
|
|
430
|
+
* in sorted (dependency) order.
|
|
431
|
+
*
|
|
432
|
+
* @param txid
|
|
433
|
+
* @returns serialized contents of this Beef with AtomicBEEF prefix.
|
|
434
|
+
*/
|
|
435
|
+
toBinaryAtomic(txid: string) {
|
|
436
|
+
this.sortTxs()
|
|
437
|
+
const tx = this.findTxid(txid)
|
|
438
|
+
if (!tx)
|
|
439
|
+
throw new Error(`${txid} does not exist in this Beef`)
|
|
440
|
+
if (this.txs[this.txs.length - 1] !== tx)
|
|
441
|
+
throw new Error(`${txid} is not the last transaction in this Beef`)
|
|
442
|
+
const writer = new Writer()
|
|
443
|
+
writer.writeUInt32LE(ATOMIC_BEEF)
|
|
444
|
+
writer.write(toArray(txid, 'hex'))
|
|
445
|
+
this.toWriter(writer)
|
|
416
446
|
return writer.toArray()
|
|
417
447
|
}
|
|
418
448
|
|
|
@@ -429,7 +459,7 @@ export class Beef {
|
|
|
429
459
|
let atomicTxid: string | undefined = undefined
|
|
430
460
|
if (version === ATOMIC_BEEF) {
|
|
431
461
|
// Skip the txid and re-read the BEEF version
|
|
432
|
-
atomicTxid = toHex(br.
|
|
462
|
+
atomicTxid = toHex(br.read(32))
|
|
433
463
|
version = br.readUInt32LE()
|
|
434
464
|
}
|
|
435
465
|
if (version !== BEEF_MAGIC && version !== BEEF_MAGIC_V2) { throw new Error(`Serialized BEEF must start with ${BEEF_MAGIC} or ${BEEF_MAGIC_V2} but starts with ${version}`) }
|
|
@@ -138,7 +138,18 @@ export default class Transaction {
|
|
|
138
138
|
|
|
139
139
|
// Ensure that all transactions are part of the dependency graph of the subject transaction
|
|
140
140
|
const validTxids = new Set<string>()
|
|
141
|
+
// All BUMP level 0 hashes are valid.
|
|
142
|
+
for (const bump of BUMPs) {
|
|
143
|
+
for (const n of bump.path[0])
|
|
144
|
+
if (n.hash)
|
|
145
|
+
validTxids.add(n.hash)
|
|
146
|
+
}
|
|
147
|
+
// To keep track of which transactions were used.
|
|
148
|
+
const unusedTxTxids = new Set<string>()
|
|
149
|
+
for (const txid of Object.keys(transactions)) unusedTxTxids.add(txid)
|
|
150
|
+
|
|
141
151
|
const traverseDependencies = (txid: string) => {
|
|
152
|
+
unusedTxTxids.delete(txid)
|
|
142
153
|
if (validTxids.has(txid)) {
|
|
143
154
|
return
|
|
144
155
|
}
|
|
@@ -156,10 +167,8 @@ export default class Transaction {
|
|
|
156
167
|
traverseDependencies(subjectTXID)
|
|
157
168
|
|
|
158
169
|
// Check for any unrelated transactions
|
|
159
|
-
for (const txid
|
|
160
|
-
|
|
161
|
-
throw new Error(`Unrelated transaction with TXID ${txid} found in Atomic BEEF data.`)
|
|
162
|
-
}
|
|
170
|
+
for (const txid of unusedTxTxids) {
|
|
171
|
+
throw new Error(`Unrelated transaction with TXID ${txid} found in Atomic BEEF data.`)
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
// Build the transaction by linking inputs and merkle paths
|
|
@@ -101,7 +101,7 @@ describe('Beef tests', () => {
|
|
|
101
101
|
}
|
|
102
102
|
})
|
|
103
103
|
|
|
104
|
-
test('
|
|
104
|
+
test('1_all merkleRoots equal', async () => {
|
|
105
105
|
{
|
|
106
106
|
const beef = Beef.fromString(beefs[0])
|
|
107
107
|
expect(beef.isValid(undefined)).toBe(true)
|
|
@@ -115,7 +115,7 @@ describe('Beef tests', () => {
|
|
|
115
115
|
}
|
|
116
116
|
})
|
|
117
117
|
|
|
118
|
-
test('
|
|
118
|
+
test('2_allowTxidOnly', async () => {
|
|
119
119
|
{
|
|
120
120
|
const beef = Beef.fromString(beefs[0])
|
|
121
121
|
expect(beef.isValid(undefined)).toBe(true)
|
|
@@ -125,7 +125,7 @@ describe('Beef tests', () => {
|
|
|
125
125
|
}
|
|
126
126
|
})
|
|
127
127
|
|
|
128
|
-
test('
|
|
128
|
+
test('3_removeExistingTxid', async () => {
|
|
129
129
|
{
|
|
130
130
|
const beef = Beef.fromString(beefs[0])
|
|
131
131
|
expect(beef.isValid(undefined)).toBe(true)
|
|
@@ -165,7 +165,7 @@ describe('Beef tests', () => {
|
|
|
165
165
|
}
|
|
166
166
|
})
|
|
167
167
|
|
|
168
|
-
test('
|
|
168
|
+
test('5_mergeBeef', async () => {
|
|
169
169
|
{
|
|
170
170
|
const beef = Beef.fromString(beefs[0])
|
|
171
171
|
const beefB = Beef.fromString(beefs[0])
|
|
@@ -201,7 +201,7 @@ describe('Beef tests', () => {
|
|
|
201
201
|
}
|
|
202
202
|
})
|
|
203
203
|
|
|
204
|
-
test('
|
|
204
|
+
test('6_BeefParty', async () => {
|
|
205
205
|
|
|
206
206
|
const bp = new BeefParty(['b', 'c'])
|
|
207
207
|
expect(bp.isParty('a')).toBe(false)
|
|
@@ -254,7 +254,7 @@ describe('Beef tests', () => {
|
|
|
254
254
|
}
|
|
255
255
|
})
|
|
256
256
|
|
|
257
|
-
test('
|
|
257
|
+
test('7_AtomicBeef', async () => {
|
|
258
258
|
{
|
|
259
259
|
const beef = Beef.fromString(beefs[0])
|
|
260
260
|
expect(beef.toHex()).toBe(beefs[0])
|
|
@@ -291,6 +291,20 @@ describe('Beef tests', () => {
|
|
|
291
291
|
expect(beef2.toHex()).toBe(beefHex)
|
|
292
292
|
}
|
|
293
293
|
})
|
|
294
|
+
|
|
295
|
+
test('8_toBinaryAtomic', async () => {
|
|
296
|
+
{
|
|
297
|
+
const beef = Beef.fromString(beefs[0])
|
|
298
|
+
const tx = Transaction.fromHex(txs[0])
|
|
299
|
+
beef.mergeTransaction(tx)
|
|
300
|
+
const sr = beef.sortTxs()
|
|
301
|
+
const log = beef.toLogString()
|
|
302
|
+
const atomic = beef.toBinaryAtomic(tx.id('hex'))
|
|
303
|
+
const t2 = Transaction.fromAtomicBEEF(atomic)
|
|
304
|
+
const beef2 = t2.toAtomicBEEF()
|
|
305
|
+
expect(atomic).toEqual(beef2)
|
|
306
|
+
}
|
|
307
|
+
})
|
|
294
308
|
})
|
|
295
309
|
|
|
296
310
|
const txs: string[] = [
|
|
@@ -16,7 +16,7 @@ export function defaultHttpClient (): HttpClient {
|
|
|
16
16
|
|
|
17
17
|
if (typeof window !== 'undefined' && typeof window.fetch === 'function') {
|
|
18
18
|
// Use fetch in a browser environment
|
|
19
|
-
return new FetchHttpClient(window.fetch)
|
|
19
|
+
return new FetchHttpClient(window.fetch.bind(window))
|
|
20
20
|
} else if (typeof require !== 'undefined') {
|
|
21
21
|
// Use Node.js https module
|
|
22
22
|
// eslint-disable-next-line
|