@bsv/wallet-toolbox 1.1.13 → 1.1.15
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/docs/README.md +8 -2
- package/docs/client.md +465 -346
- package/docs/open-rpc/index.html +46 -0
- package/docs/services.md +236 -211
- package/docs/setup.md +32 -4
- package/docs/storage.md +30 -5
- package/docs/wallet.md +465 -346
- package/out/src/Setup.d.ts.map +1 -1
- package/out/src/Setup.js.map +1 -1
- package/out/src/SetupClient.d.ts +9 -0
- package/out/src/SetupClient.d.ts.map +1 -1
- package/out/src/SetupClient.js +19 -3
- package/out/src/SetupClient.js.map +1 -1
- package/out/src/Wallet.d.ts +6 -0
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +57 -0
- package/out/src/Wallet.js.map +1 -1
- package/out/src/sdk/WalletServices.interfaces.d.ts +18 -13
- package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/out/src/services/Services.d.ts +4 -11
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +19 -37
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/__tests/ARC.test.d.ts +2 -0
- package/out/src/services/__tests/ARC.test.d.ts.map +1 -0
- package/out/src/services/__tests/ARC.test.js +98 -0
- package/out/src/services/__tests/ARC.test.js.map +1 -0
- package/out/src/services/__tests/arcServices.test.d.ts +2 -0
- package/out/src/services/__tests/arcServices.test.d.ts.map +1 -0
- package/out/src/services/__tests/arcServices.test.js +7 -0
- package/out/src/services/__tests/arcServices.test.js.map +1 -0
- package/out/src/services/__tests/postBeef.test.js +45 -7
- package/out/src/services/__tests/postBeef.test.js.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
- package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +16 -4
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/src/services/providers/ARC.d.ts +91 -0
- package/out/src/services/providers/ARC.d.ts.map +1 -0
- package/out/src/services/providers/ARC.js +192 -0
- package/out/src/services/providers/ARC.js.map +1 -0
- package/out/src/services/providers/SdkWhatsOnChain.d.ts +21 -0
- package/out/src/services/providers/SdkWhatsOnChain.d.ts.map +1 -0
- package/out/src/services/providers/SdkWhatsOnChain.js +67 -0
- package/out/src/services/providers/SdkWhatsOnChain.js.map +1 -0
- package/out/src/services/providers/WhatsOnChain.d.ts +35 -0
- package/out/src/services/providers/WhatsOnChain.d.ts.map +1 -0
- package/out/src/services/providers/WhatsOnChain.js +266 -0
- package/out/src/services/providers/WhatsOnChain.js.map +1 -0
- package/out/src/services/providers/__tests/WhatsOnChain.test.d.ts +2 -0
- package/out/src/services/providers/__tests/WhatsOnChain.test.d.ts.map +1 -0
- package/out/src/services/providers/__tests/WhatsOnChain.test.js +176 -0
- package/out/src/services/providers/__tests/WhatsOnChain.test.js.map +1 -0
- package/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/out/src/storage/methods/createAction.js +9 -2
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/src/storage/methods/generateChange.d.ts +12 -1
- package/out/src/storage/methods/generateChange.d.ts.map +1 -1
- package/out/src/storage/methods/generateChange.js +24 -1
- package/out/src/storage/methods/generateChange.js.map +1 -1
- package/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/out/src/storage/methods/processAction.js +1 -1
- package/out/src/storage/methods/processAction.js.map +1 -1
- package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.js +0 -1
- package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.js.map +1 -1
- package/out/src/storage/sync/StorageMySQLDojoReader.js +1 -1
- package/out/src/storage/sync/StorageMySQLDojoReader.js.map +1 -1
- package/out/src/utility/utilityHelpers.js +1 -1
- package/out/src/utility/utilityHelpers.js.map +1 -1
- package/out/test/Wallet/StorageClient/storageClient.man.test.js +22 -3
- package/out/test/Wallet/StorageClient/storageClient.man.test.js.map +1 -1
- package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.js +40 -0
- package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.js.map +1 -1
- package/out/test/services/Services.test.js +0 -31
- package/out/test/services/Services.test.js.map +1 -1
- package/out/test/utils/TestUtilsWalletStorage.d.ts +26 -18
- package/out/test/utils/TestUtilsWalletStorage.d.ts.map +1 -1
- package/out/test/utils/TestUtilsWalletStorage.js +135 -27
- package/out/test/utils/TestUtilsWalletStorage.js.map +1 -1
- package/out/test/wallet/list/listActions2.test.js +36 -2
- package/out/test/wallet/list/listActions2.test.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +4 -6
- package/src/Setup.ts +0 -1
- package/src/SetupClient.ts +25 -6
- package/src/Wallet.ts +66 -2
- package/src/sdk/WalletServices.interfaces.ts +19 -14
- package/src/services/Services.ts +23 -62
- package/src/services/__tests/ARC.test.ts +110 -0
- package/src/services/__tests/arcServices.test.ts +8 -0
- package/src/services/__tests/postBeef.test.ts +47 -9
- package/src/services/createDefaultWalletServicesOptions.ts +19 -6
- package/src/services/providers/ARC.ts +289 -0
- package/src/services/providers/SdkWhatsOnChain.ts +96 -0
- package/src/services/providers/WhatsOnChain.ts +369 -0
- package/src/services/providers/__tests/WhatsOnChain.test.ts +227 -0
- package/src/storage/methods/createAction.ts +26 -4
- package/src/storage/methods/generateChange.ts +42 -2
- package/src/storage/methods/processAction.ts +2 -1
- package/src/storage/schema/entities/__tests/ProvenTxTests.test.ts +0 -1
- package/src/storage/sync/StorageMySQLDojoReader.ts +1 -1
- package/src/utility/utilityHelpers.ts +1 -1
- package/test/Wallet/StorageClient/storageClient.man.test.ts +30 -4
- package/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.ts +54 -0
- package/test/services/Services.test.ts +0 -30
- package/test/utils/TestUtilsWalletStorage.ts +174 -45
- package/test/wallet/list/listActions2.test.ts +4 -7
- package/out/src/services/__tests/postBeefToArcTaal.test.d.ts +0 -2
- package/out/src/services/__tests/postBeefToArcTaal.test.d.ts.map +0 -1
- package/out/src/services/__tests/postBeefToArcTaal.test.js +0 -479
- package/out/src/services/__tests/postBeefToArcTaal.test.js.map +0 -1
- package/out/src/services/__tests/postTxs.test.d.ts +0 -2
- package/out/src/services/__tests/postTxs.test.d.ts.map +0 -1
- package/out/src/services/__tests/postTxs.test.js +0 -28
- package/out/src/services/__tests/postTxs.test.js.map +0 -1
- package/out/src/services/providers/arcServices.d.ts +0 -62
- package/out/src/services/providers/arcServices.d.ts.map +0 -1
- package/out/src/services/providers/arcServices.js +0 -375
- package/out/src/services/providers/arcServices.js.map +0 -1
- package/out/src/services/providers/whatsonchain.d.ts +0 -17
- package/out/src/services/providers/whatsonchain.d.ts.map +0 -1
- package/out/src/services/providers/whatsonchain.js +0 -130
- package/out/src/services/providers/whatsonchain.js.map +0 -1
- package/out/test/examples/README.man.test.d.ts +0 -2
- package/out/test/examples/README.man.test.d.ts.map +0 -1
- package/out/test/examples/README.man.test.js +0 -47
- package/out/test/examples/README.man.test.js.map +0 -1
- package/src/services/__tests/postBeefToArcTaal.test.ts +0 -487
- package/src/services/__tests/postTxs.test.ts +0 -28
- package/src/services/providers/arcServices.ts +0 -578
- package/src/services/providers/whatsonchain.ts +0 -170
- package/test/examples/README.man.test.ts +0 -53
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Beef, Utils } from '@bsv/sdk'
|
|
2
|
-
import { Services } from '../../index.client'
|
|
3
|
-
|
|
4
|
-
describe('postTxs service tests', () => {
|
|
5
|
-
jest.setTimeout(99999999)
|
|
6
|
-
|
|
7
|
-
test('0', async () => {
|
|
8
|
-
const options = Services.createDefaultOptions('main')
|
|
9
|
-
const services = new Services(options)
|
|
10
|
-
|
|
11
|
-
const txid =
|
|
12
|
-
'b56ccf7dd0eb6bb0341cb92a2045d902106e4c2add0a4af057c85e9dfaaebddf'
|
|
13
|
-
const rawTx = await services.getRawTx(txid)
|
|
14
|
-
const rawTxHex = Utils.toHex(rawTx.rawTx!)
|
|
15
|
-
const beef = new Beef()
|
|
16
|
-
beef.mergeRawTx(rawTx.rawTx!)
|
|
17
|
-
const r = await services.postTxs(beef, [txid])
|
|
18
|
-
if (r[0].status === 'error') {
|
|
19
|
-
console.log(`
|
|
20
|
-
${r[0].error?.message}
|
|
21
|
-
${beef.toLogString()}
|
|
22
|
-
${beef.toHex()}
|
|
23
|
-
`)
|
|
24
|
-
}
|
|
25
|
-
if (r[0].error?.message != 'broadcastMany error: error code: 502')
|
|
26
|
-
expect(r[0].status).toBe('success')
|
|
27
|
-
})
|
|
28
|
-
})
|
|
@@ -1,578 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Transaction as BsvTransaction,
|
|
3
|
-
ARC,
|
|
4
|
-
ArcConfig,
|
|
5
|
-
Beef,
|
|
6
|
-
defaultHttpClient,
|
|
7
|
-
HttpClient,
|
|
8
|
-
HttpClientRequestOptions,
|
|
9
|
-
MerklePath
|
|
10
|
-
} from '@bsv/sdk'
|
|
11
|
-
import { asArray, randomBytesHex, sdk } from '../../index.client'
|
|
12
|
-
|
|
13
|
-
import axios from 'axios'
|
|
14
|
-
import { Readable } from 'stream'
|
|
15
|
-
import { PostTxResultForTxid } from '../../sdk'
|
|
16
|
-
|
|
17
|
-
const BEEF_V1 = 4022206465 // 0100BEEF in LE order
|
|
18
|
-
const BEEF_V2 = 4022206466 // 0200BEEF in LE order
|
|
19
|
-
|
|
20
|
-
// Documentation:
|
|
21
|
-
// https://docs.taal.com/
|
|
22
|
-
// https://docs.taal.com/core-products/transaction-processing/arc-endpoints
|
|
23
|
-
// https://bitcoin-sv.github.io/arc/api.html
|
|
24
|
-
|
|
25
|
-
export interface ArcServiceConfig {
|
|
26
|
-
name: string
|
|
27
|
-
url: string
|
|
28
|
-
arcConfig: ArcConfig
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function getTaalArcServiceConfig(
|
|
32
|
-
chain: sdk.Chain,
|
|
33
|
-
apiKey: string
|
|
34
|
-
): ArcServiceConfig {
|
|
35
|
-
return {
|
|
36
|
-
name: 'TaalArc',
|
|
37
|
-
url:
|
|
38
|
-
chain === 'main'
|
|
39
|
-
? 'https://api.taal.com/arc'
|
|
40
|
-
: 'https://arc-test.taal.com',
|
|
41
|
-
arcConfig: {
|
|
42
|
-
apiKey,
|
|
43
|
-
deploymentId: `WalletServices-${randomBytesHex(16)}`
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function makePostTxsToTaalARC(
|
|
49
|
-
config: ArcServiceConfig
|
|
50
|
-
): sdk.PostTxsService {
|
|
51
|
-
return (beef: Beef, txids: string[], services: sdk.WalletServices) => {
|
|
52
|
-
return postTxsToTaalArcMiner(beef, txids, config, services)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function makePostBeefToTaalARC(
|
|
57
|
-
config: ArcServiceConfig
|
|
58
|
-
): sdk.PostBeefService {
|
|
59
|
-
return (beef: Beef, txids: string[], services: sdk.WalletServices) => {
|
|
60
|
-
return postBeefToTaalArcMiner(beef, txids, config, services)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function makeGetMerklePathFromTaalARC(
|
|
65
|
-
config: ArcServiceConfig
|
|
66
|
-
): sdk.GetMerklePathService {
|
|
67
|
-
return (txid: string, chain: sdk.Chain, services: sdk.WalletServices) => {
|
|
68
|
-
return getMerklePathFromTaalARC(txid, config, services)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
class ArcServices {
|
|
73
|
-
readonly URL: string
|
|
74
|
-
readonly apiKey: string | undefined
|
|
75
|
-
readonly deploymentId: string
|
|
76
|
-
readonly callbackUrl: string | undefined
|
|
77
|
-
readonly callbackToken: string | undefined
|
|
78
|
-
readonly headers: Record<string, string> | undefined
|
|
79
|
-
private readonly httpClient: HttpClient
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Constructs an instance of the ARC broadcaster.
|
|
83
|
-
*
|
|
84
|
-
* @param {string} URL - The URL endpoint for the ARC API.
|
|
85
|
-
* @param {ArcConfig} config - Configuration options for the ARC broadcaster.
|
|
86
|
-
*/
|
|
87
|
-
constructor(URL: string, config: ArcConfig) {
|
|
88
|
-
this.URL = URL
|
|
89
|
-
const {
|
|
90
|
-
apiKey,
|
|
91
|
-
deploymentId,
|
|
92
|
-
httpClient,
|
|
93
|
-
callbackToken,
|
|
94
|
-
callbackUrl,
|
|
95
|
-
headers
|
|
96
|
-
} = config
|
|
97
|
-
this.apiKey = apiKey
|
|
98
|
-
this.httpClient = httpClient ?? defaultHttpClient()
|
|
99
|
-
this.deploymentId = deploymentId || `WalletServices-${randomBytesHex(16)}`
|
|
100
|
-
this.callbackToken = callbackToken
|
|
101
|
-
this.callbackUrl = callbackUrl
|
|
102
|
-
this.headers = headers
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Unfortunately this seems to only work for recently submitted txids...
|
|
107
|
-
* @param txid
|
|
108
|
-
* @returns
|
|
109
|
-
*/
|
|
110
|
-
async getTxStatus(txid: string): Promise<ArcMinerGetTxData> {
|
|
111
|
-
const requestOptions: HttpClientRequestOptions = {
|
|
112
|
-
method: 'GET',
|
|
113
|
-
headers: this.requestHeaders()
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const response = await this.httpClient.request<ArcMinerGetTxData>(
|
|
117
|
-
`${this.URL}/v1/tx/${txid}`,
|
|
118
|
-
requestOptions
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
return response.data
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
requestHeaders() {
|
|
125
|
-
const headers: Record<string, string> = {
|
|
126
|
-
'Content-Type': 'application/json',
|
|
127
|
-
'XDeployment-ID': this.deploymentId
|
|
128
|
-
}
|
|
129
|
-
if (this.apiKey) {
|
|
130
|
-
headers.Authorization = `Bearer ${this.apiKey}`
|
|
131
|
-
}
|
|
132
|
-
if (this.callbackUrl) {
|
|
133
|
-
headers['X-CallbackUrl'] = this.callbackUrl
|
|
134
|
-
}
|
|
135
|
-
if (this.callbackToken) {
|
|
136
|
-
headers['X-CallbackToken'] = this.callbackToken
|
|
137
|
-
}
|
|
138
|
-
if (this.headers) {
|
|
139
|
-
for (const key in this.headers) {
|
|
140
|
-
headers[key] = this.headers[key]
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return headers
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export async function getMerklePathFromTaalARC(
|
|
148
|
-
txid: string,
|
|
149
|
-
config: ArcServiceConfig,
|
|
150
|
-
services: sdk.WalletServices
|
|
151
|
-
): Promise<sdk.GetMerklePathResult> {
|
|
152
|
-
const r: sdk.GetMerklePathResult = { name: config.name }
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
const arc = new ArcServices(config.url, config.arcConfig)
|
|
156
|
-
|
|
157
|
-
const rr = await arc.getTxStatus(txid)
|
|
158
|
-
|
|
159
|
-
if (rr.status === 200 && rr.merklePath) {
|
|
160
|
-
const mp = MerklePath.fromHex(rr.merklePath)
|
|
161
|
-
r.merklePath = mp
|
|
162
|
-
r.header = await services.hashToHeader(rr.blockHash)
|
|
163
|
-
}
|
|
164
|
-
} catch (eu: unknown) {
|
|
165
|
-
r.error = sdk.WalletError.fromUnknown(eu)
|
|
166
|
-
}
|
|
167
|
-
return r
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
*
|
|
172
|
-
* @param txs All transactions must have source transactions. Will just source locking scripts and satoshis do?? toHexEF() is used.
|
|
173
|
-
* @param config
|
|
174
|
-
*/
|
|
175
|
-
export async function postTxsToTaalArcMiner(
|
|
176
|
-
beef: Beef,
|
|
177
|
-
txids: string[],
|
|
178
|
-
config: ArcServiceConfig,
|
|
179
|
-
services: sdk.WalletServices
|
|
180
|
-
): Promise<sdk.PostTxsResult> {
|
|
181
|
-
const r: sdk.PostTxsResult = {
|
|
182
|
-
name: config.name,
|
|
183
|
-
status: 'error',
|
|
184
|
-
txidResults: []
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
const arc = new ARC(config.url, config.arcConfig)
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* This service requires an array of EF serialized transactions:
|
|
192
|
-
* Pull the transactions matching txids array out of the Beef and fill in input sourceTransations,
|
|
193
|
-
* either from Beef or by external service lookup.
|
|
194
|
-
*/
|
|
195
|
-
const txs: BsvTransaction[] = []
|
|
196
|
-
for (const txid of txids) {
|
|
197
|
-
const btx = beef.findTxid(txid)
|
|
198
|
-
if (btx) {
|
|
199
|
-
const tx = btx.tx!
|
|
200
|
-
for (const input of tx.inputs) {
|
|
201
|
-
if (!input.sourceTXID || input.sourceTXID === '0'.repeat(64)) continue // all zero txid is a coinbase input.
|
|
202
|
-
let itx = beef.findTxid(input.sourceTXID!)
|
|
203
|
-
if (!itx) {
|
|
204
|
-
const rawTx = await services.getRawTx(input.sourceTXID!)
|
|
205
|
-
if (!rawTx || !rawTx.rawTx)
|
|
206
|
-
throw new sdk.WERR_INVALID_PARAMETER(
|
|
207
|
-
'sourceTXID',
|
|
208
|
-
`contained in beef or found on chain. ${input.sourceTXID}`
|
|
209
|
-
)
|
|
210
|
-
beef.mergeRawTx(rawTx.rawTx!)
|
|
211
|
-
itx = beef.findTxid(input.sourceTXID!)
|
|
212
|
-
}
|
|
213
|
-
input.sourceTransaction = itx!.tx
|
|
214
|
-
}
|
|
215
|
-
txs.push(tx)
|
|
216
|
-
} else
|
|
217
|
-
throw new sdk.WERR_INVALID_PARAMETER(
|
|
218
|
-
'beef',
|
|
219
|
-
`merged with rawTxs matching txids. Missing ${txid}`
|
|
220
|
-
)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const rrs = (await arc.broadcastMany(txs)) as ArcMinerPostTxsData[] | string
|
|
224
|
-
|
|
225
|
-
if (typeof rrs === 'string') {
|
|
226
|
-
const rawTxs = txs.map(tx => {
|
|
227
|
-
return { rawTx: tx.toHexEF() }
|
|
228
|
-
})
|
|
229
|
-
console.log(`const rawTxs = '${JSON.stringify(rawTxs)}`)
|
|
230
|
-
throw new sdk.WERR_BAD_REQUEST(`broadcastMany error: ${rrs}`)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
r.status = 'success'
|
|
234
|
-
for (const txid of txids) {
|
|
235
|
-
const txr: PostTxResultForTxid = { txid, status: 'success' }
|
|
236
|
-
const rr = rrs.find(r => r.txid === txid)
|
|
237
|
-
if (!rr) {
|
|
238
|
-
r.status = txr.status = 'error'
|
|
239
|
-
} else {
|
|
240
|
-
txr.data = rr
|
|
241
|
-
if (rr.status !== 200) r.status = txr.status = 'error'
|
|
242
|
-
else {
|
|
243
|
-
txr.blockHash = rr.blockHash
|
|
244
|
-
txr.blockHeight = rr.blockHeight
|
|
245
|
-
txr.merklePath = !rr.merklePath
|
|
246
|
-
? undefined
|
|
247
|
-
: MerklePath.fromHex(rr.merklePath)
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
r.txidResults.push(txr)
|
|
251
|
-
}
|
|
252
|
-
r.data = rrs
|
|
253
|
-
} catch (eu: unknown) {
|
|
254
|
-
r.error = sdk.WalletError.fromUnknown(eu)
|
|
255
|
-
}
|
|
256
|
-
return r
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export interface ArcMinerGetTxData {
|
|
260
|
-
status: number // 200
|
|
261
|
-
title: string // OK
|
|
262
|
-
blockHash: string
|
|
263
|
-
blockHeight: number
|
|
264
|
-
competingTxs: null | string[]
|
|
265
|
-
extraInfo: string
|
|
266
|
-
merklePath: string
|
|
267
|
-
timestamp: string // ISO Z
|
|
268
|
-
txid: string
|
|
269
|
-
txStatus: string // 'SEEN_IN_ORPHAN_MEMPOOL'
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export interface ArcMinerPostTxsData {
|
|
273
|
-
status: number // 200
|
|
274
|
-
title: string // OK
|
|
275
|
-
blockHash: string
|
|
276
|
-
blockHeight: number
|
|
277
|
-
competingTxs: null | string[]
|
|
278
|
-
extraInfo: string
|
|
279
|
-
merklePath: string
|
|
280
|
-
timestamp: string // ISO Z
|
|
281
|
-
txid: string
|
|
282
|
-
txStatus: string // 'SEEN_IN_ORPHAN_MEMPOOL'
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export interface ArcMinerPostBeefDataApi {
|
|
286
|
-
status: number // 200
|
|
287
|
-
title: string // "OK",
|
|
288
|
-
blockHash?: string // ""
|
|
289
|
-
blockHeight?: number // 0
|
|
290
|
-
competingTxs?: null
|
|
291
|
-
extraInfo: string // ""
|
|
292
|
-
merklePath?: string // ""
|
|
293
|
-
timestamp?: string // "2024-08-23T12:55:26.229904Z",
|
|
294
|
-
txid?: string // "272b5cdca9a0aa51846df9be29ee366ff85902691d38210e8c4be2fead3823a5",
|
|
295
|
-
txStatus?: string // "SEEN_ON_NETWORK",
|
|
296
|
-
|
|
297
|
-
type?: string // url
|
|
298
|
-
detail?: string
|
|
299
|
-
instance?: string
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
export async function postBeefToTaalArcMiner(
|
|
303
|
-
beef: Beef,
|
|
304
|
-
txids: string[],
|
|
305
|
-
config: ArcServiceConfig,
|
|
306
|
-
services: sdk.WalletServices
|
|
307
|
-
): Promise<sdk.PostBeefResult> {
|
|
308
|
-
const r1 = await postBeefToArcMiner(beef, txids, config)
|
|
309
|
-
return r1
|
|
310
|
-
|
|
311
|
-
if (r1.status === 'success') return r1
|
|
312
|
-
|
|
313
|
-
const datas: object = { r1: r1.data }
|
|
314
|
-
|
|
315
|
-
const r2 = await services.postTxs(beef, txids)
|
|
316
|
-
|
|
317
|
-
const r3: sdk.PostBeefResult = {
|
|
318
|
-
name: config.name,
|
|
319
|
-
status: 'success',
|
|
320
|
-
data: {},
|
|
321
|
-
txidResults: []
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
for (const txid of txids) {
|
|
325
|
-
const rawTx = beef.findTxid(txid)!.rawTx!
|
|
326
|
-
const rt = await postBeefToArcMiner(rawTx, [txid], config)
|
|
327
|
-
if (rt.status === 'error') r3.status = 'error'
|
|
328
|
-
r3.data![txid] = rt.data
|
|
329
|
-
r3.txidResults.push(rt.txidResults[0])
|
|
330
|
-
}
|
|
331
|
-
datas['r3'] = r3.data
|
|
332
|
-
r3.data = datas
|
|
333
|
-
return r3
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
export async function postBeefToArcMiner(
|
|
337
|
-
beef: Beef | number[],
|
|
338
|
-
txids: string[],
|
|
339
|
-
config: ArcServiceConfig
|
|
340
|
-
): Promise<sdk.PostBeefResult> {
|
|
341
|
-
const m = { ...config }
|
|
342
|
-
|
|
343
|
-
let url = ''
|
|
344
|
-
|
|
345
|
-
let r: sdk.PostBeefResult | undefined = undefined
|
|
346
|
-
|
|
347
|
-
// HACK to resolve ARC error when row has zero leaves.
|
|
348
|
-
// beef.addComputedLeaves()
|
|
349
|
-
|
|
350
|
-
let beefBinary: number[]
|
|
351
|
-
|
|
352
|
-
if (Array.isArray(beef)) beefBinary = beef
|
|
353
|
-
else {
|
|
354
|
-
// HACK to resolve ARC not handling V2 Beef after change Beef class to always serialize as V2 if default constructed:
|
|
355
|
-
beef.version = BEEF_V1
|
|
356
|
-
beefBinary = beef.toBinary()
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
try {
|
|
360
|
-
const length = beefBinary.length
|
|
361
|
-
|
|
362
|
-
const makeRequestHeaders = () => {
|
|
363
|
-
const headers: Record<string, string> = {
|
|
364
|
-
'Content-Type': 'application/octet-stream',
|
|
365
|
-
'Content-Length': length.toString(),
|
|
366
|
-
'XDeployment-ID':
|
|
367
|
-
m.arcConfig.deploymentId || `WalletServices-${randomBytesHex(16)}`
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
if (m.arcConfig.apiKey) {
|
|
371
|
-
headers['Authorization'] = `Bearer ${m.arcConfig.apiKey}`
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
return headers
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const headers = makeRequestHeaders()
|
|
378
|
-
|
|
379
|
-
const stream = new Readable({
|
|
380
|
-
read() {
|
|
381
|
-
this.push(Buffer.from(beefBinary as number[]))
|
|
382
|
-
this.push(null)
|
|
383
|
-
}
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
url = `${config.url}/v1/tx`
|
|
387
|
-
|
|
388
|
-
const data = await axios.post(url, stream, {
|
|
389
|
-
headers,
|
|
390
|
-
maxBodyLength: Infinity,
|
|
391
|
-
validateStatus: () => true
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
if (!data || !data.data) throw new sdk.WERR_BAD_REQUEST('no response data')
|
|
395
|
-
if (
|
|
396
|
-
data.data === 'No Authorization' ||
|
|
397
|
-
data.status === 403 ||
|
|
398
|
-
data.statusText === 'Forbiden'
|
|
399
|
-
)
|
|
400
|
-
throw new sdk.WERR_BAD_REQUEST('No Authorization')
|
|
401
|
-
if (typeof data.data !== 'object')
|
|
402
|
-
throw new sdk.WERR_BAD_REQUEST('no response data object')
|
|
403
|
-
|
|
404
|
-
const dd = data.data as ArcMinerPostBeefDataApi
|
|
405
|
-
|
|
406
|
-
r = makePostBeefResult(dd, config, beefBinary, txids)
|
|
407
|
-
} catch (err: unknown) {
|
|
408
|
-
console.error(err)
|
|
409
|
-
const error = new sdk.WERR_INTERNAL(
|
|
410
|
-
`service: ${url}, error: ${JSON.stringify(sdk.WalletError.fromUnknown(err))}`
|
|
411
|
-
)
|
|
412
|
-
r = makeErrorResult(error, config, beefBinary, txids)
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return r
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
export function makePostBeefResult(
|
|
419
|
-
dd: ArcMinerPostBeefDataApi,
|
|
420
|
-
miner: ArcServiceConfig,
|
|
421
|
-
beef: number[],
|
|
422
|
-
txids: string[]
|
|
423
|
-
): sdk.PostBeefResult {
|
|
424
|
-
let r: sdk.PostBeefResult
|
|
425
|
-
switch (dd.status) {
|
|
426
|
-
case 200: // Success
|
|
427
|
-
r = makeSuccessResult(dd, miner, beef, txids)
|
|
428
|
-
break
|
|
429
|
-
case 400: // Bad Request
|
|
430
|
-
r = makeErrorResult(new sdk.WERR_BAD_REQUEST(), miner, beef, txids, dd)
|
|
431
|
-
break
|
|
432
|
-
case 401: // Security Failed
|
|
433
|
-
r = makeErrorResult(
|
|
434
|
-
new sdk.WERR_BAD_REQUEST(`Security Failed (401)`),
|
|
435
|
-
miner,
|
|
436
|
-
beef,
|
|
437
|
-
txids,
|
|
438
|
-
dd
|
|
439
|
-
)
|
|
440
|
-
break
|
|
441
|
-
case 409: // Generic Error
|
|
442
|
-
case 422: // RFC 7807 Error
|
|
443
|
-
case 460: // Not Extended Format
|
|
444
|
-
case 467: // Mined Ancestor Missing
|
|
445
|
-
case 468: // Invalid BUMPs
|
|
446
|
-
r = makeErrorResult(
|
|
447
|
-
new sdk.WERR_BAD_REQUEST(`status ${dd.status}, title ${dd.title}`),
|
|
448
|
-
miner,
|
|
449
|
-
beef,
|
|
450
|
-
txids,
|
|
451
|
-
dd
|
|
452
|
-
)
|
|
453
|
-
break
|
|
454
|
-
case 461: // Malformed Transaction
|
|
455
|
-
case 463: // Malformed Transaction
|
|
456
|
-
case 464: // Invalid Outputs
|
|
457
|
-
r = makeErrorResult(
|
|
458
|
-
new sdk.WERR_BAD_REQUEST(`status ${dd.status}, title ${dd.title}`),
|
|
459
|
-
miner,
|
|
460
|
-
beef,
|
|
461
|
-
txids,
|
|
462
|
-
dd
|
|
463
|
-
)
|
|
464
|
-
break
|
|
465
|
-
case 462: // Invalid Inputs
|
|
466
|
-
if (dd.txid)
|
|
467
|
-
r = makeErrorResult(
|
|
468
|
-
new sdk.WERR_BAD_REQUEST(`status ${dd.status}, title ${dd.title}`),
|
|
469
|
-
miner,
|
|
470
|
-
beef,
|
|
471
|
-
txids,
|
|
472
|
-
dd
|
|
473
|
-
)
|
|
474
|
-
else
|
|
475
|
-
r = makeErrorResult(
|
|
476
|
-
new sdk.WERR_BAD_REQUEST(`status ${dd.status}, title ${dd.title}`),
|
|
477
|
-
miner,
|
|
478
|
-
beef,
|
|
479
|
-
txids,
|
|
480
|
-
dd
|
|
481
|
-
)
|
|
482
|
-
break
|
|
483
|
-
case 465: // Fee Too Low
|
|
484
|
-
case 473: // Cumulative Fee Validation Failed
|
|
485
|
-
r = makeErrorResult(
|
|
486
|
-
new sdk.WERR_BAD_REQUEST(`status ${dd.status}, title ${dd.title}`),
|
|
487
|
-
miner,
|
|
488
|
-
beef,
|
|
489
|
-
txids,
|
|
490
|
-
dd
|
|
491
|
-
)
|
|
492
|
-
break
|
|
493
|
-
case 469: // Invalid Merkle Root
|
|
494
|
-
r = makeErrorResult(
|
|
495
|
-
new sdk.WERR_BAD_REQUEST(`status ${dd.status}, title ${dd.title}`),
|
|
496
|
-
miner,
|
|
497
|
-
beef,
|
|
498
|
-
txids,
|
|
499
|
-
dd
|
|
500
|
-
)
|
|
501
|
-
break
|
|
502
|
-
default:
|
|
503
|
-
r = makeErrorResult(
|
|
504
|
-
new sdk.WERR_BAD_REQUEST(`status ${dd.status}, title ${dd.title}`),
|
|
505
|
-
miner,
|
|
506
|
-
beef,
|
|
507
|
-
txids,
|
|
508
|
-
dd
|
|
509
|
-
)
|
|
510
|
-
break
|
|
511
|
-
}
|
|
512
|
-
return r
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
function makeSuccessResult(
|
|
516
|
-
dd: ArcMinerPostBeefDataApi,
|
|
517
|
-
miner: ArcServiceConfig,
|
|
518
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
519
|
-
beef: number[],
|
|
520
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
521
|
-
txids: string[]
|
|
522
|
-
): sdk.PostBeefResult {
|
|
523
|
-
const r: sdk.PostBeefResult = {
|
|
524
|
-
status: 'success',
|
|
525
|
-
name: miner.name,
|
|
526
|
-
data: dd,
|
|
527
|
-
txidResults: []
|
|
528
|
-
}
|
|
529
|
-
for (let i = 0; i < txids.length; i++) {
|
|
530
|
-
const rt: sdk.PostTxResultForTxid = {
|
|
531
|
-
txid: txids[i],
|
|
532
|
-
status: 'success'
|
|
533
|
-
}
|
|
534
|
-
if (dd.txid === txids[i]) {
|
|
535
|
-
rt.alreadyKnown =
|
|
536
|
-
!!dd.txStatus && ['SEEN_ON_NETWORK', 'MINED'].indexOf(dd.txStatus) >= 0
|
|
537
|
-
rt.txid = dd.txid
|
|
538
|
-
rt.blockHash = dd.blockHash
|
|
539
|
-
rt.blockHeight = dd.blockHeight
|
|
540
|
-
rt.merklePath = MerklePath.fromBinary(asArray(dd.merklePath!))
|
|
541
|
-
}
|
|
542
|
-
r.txidResults.push(rt)
|
|
543
|
-
}
|
|
544
|
-
return r
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
export function makeErrorResult(
|
|
548
|
-
error: sdk.WalletError,
|
|
549
|
-
miner: ArcServiceConfig,
|
|
550
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
551
|
-
beef: number[],
|
|
552
|
-
txids: string[],
|
|
553
|
-
dd?: ArcMinerPostBeefDataApi
|
|
554
|
-
): sdk.PostBeefResult {
|
|
555
|
-
const r: sdk.PostBeefResult = {
|
|
556
|
-
status: 'error',
|
|
557
|
-
name: miner.name,
|
|
558
|
-
error,
|
|
559
|
-
data: dd,
|
|
560
|
-
txidResults: []
|
|
561
|
-
}
|
|
562
|
-
for (let i = 0; i < txids.length; i++) {
|
|
563
|
-
const rt: sdk.PostTxResultForTxid = {
|
|
564
|
-
txid: txids[i],
|
|
565
|
-
status: 'error'
|
|
566
|
-
}
|
|
567
|
-
if (dd?.txid === txids[i]) {
|
|
568
|
-
rt.alreadyKnown =
|
|
569
|
-
!!dd.txStatus && ['SEEN_ON_NETWORK', 'MINED'].indexOf(dd.txStatus) >= 0
|
|
570
|
-
rt.txid = dd.txid
|
|
571
|
-
rt.blockHash = dd.blockHash
|
|
572
|
-
rt.blockHeight = dd.blockHeight
|
|
573
|
-
rt.merklePath = MerklePath.fromBinary(asArray(dd.merklePath!))
|
|
574
|
-
}
|
|
575
|
-
r.txidResults.push(rt)
|
|
576
|
-
}
|
|
577
|
-
return r
|
|
578
|
-
}
|