@xyo-network/chain-services 1.19.14 → 1.19.16
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/neutral/Election/BaseElectionService.d.ts +1 -1
- package/dist/neutral/Election/BaseElectionService.d.ts.map +1 -1
- package/dist/neutral/NetworkStakeStepReward/BaseNetworkStakeStepRewardService.d.ts +1 -1
- package/dist/neutral/NetworkStakeStepReward/BaseNetworkStakeStepRewardService.d.ts.map +1 -1
- package/dist/neutral/StepStake/BaseStepStakeService.d.ts +1 -1
- package/dist/neutral/StepStake/BaseStepStakeService.d.ts.map +1 -1
- package/dist/neutral/index.d.ts +0 -2
- package/dist/neutral/index.d.ts.map +1 -1
- package/dist/neutral/index.mjs +32 -578
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/neutral/simple/block/runner/SimpleBlockRunner.d.ts +8 -6
- package/dist/neutral/simple/block/runner/SimpleBlockRunner.d.ts.map +1 -1
- package/package.json +31 -28
- package/src/Election/BaseElectionService.ts +1 -1
- package/src/NetworkStakeStepReward/BaseNetworkStakeStepRewardService.ts +1 -1
- package/src/StepStake/BaseStepStakeService.ts +1 -1
- package/src/index.ts +0 -2
- package/src/simple/block/runner/SimpleBlockRunner.ts +12 -13
- package/src/simple/block/runner/generateTransactionFeeTransfers.ts +1 -1
- package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts +0 -64
- package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts.map +0 -1
- package/dist/neutral/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts +0 -4
- package/dist/neutral/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts.map +0 -1
- package/dist/neutral/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts +0 -4
- package/dist/neutral/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts.map +0 -1
- package/dist/neutral/PendingTransactions/index.d.ts +0 -2
- package/dist/neutral/PendingTransactions/index.d.ts.map +0 -1
- package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts +0 -47
- package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts.map +0 -1
- package/dist/neutral/StakeIntent/index.d.ts +0 -3
- package/dist/neutral/StakeIntent/index.d.ts.map +0 -1
- package/dist/neutral/StakeIntent/lib/getBlockSignedStakeDeclarations.d.ts +0 -4
- package/dist/neutral/StakeIntent/lib/getBlockSignedStakeDeclarations.d.ts.map +0 -1
- package/dist/neutral/StakeIntent/lib/index.d.ts +0 -2
- package/dist/neutral/StakeIntent/lib/index.d.ts.map +0 -1
- package/src/PendingTransactions/BasePendingTransactions.ts +0 -382
- package/src/PendingTransactions/bundledPayloadToHydratedTransaction.ts +0 -14
- package/src/PendingTransactions/hydratedTransactionToPayloadBundle.ts +0 -18
- package/src/PendingTransactions/index.ts +0 -1
- package/src/StakeIntent/XyoStakeIntentService.ts +0 -259
- package/src/StakeIntent/index.ts +0 -2
- package/src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts +0 -47
- package/src/StakeIntent/lib/index.ts +0 -1
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Hash } from '@xylabs/sdk-js'
|
|
2
|
-
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
3
|
-
import type { PayloadBundle } from '@xyo-network/payload-model'
|
|
4
|
-
import { PayloadBundleSchema } from '@xyo-network/payload-model'
|
|
5
|
-
import type { SignedHydratedTransactionWithHashMeta } from '@xyo-network/xl1-sdk'
|
|
6
|
-
import { flattenHydratedTransaction } from '@xyo-network/xl1-sdk'
|
|
7
|
-
|
|
8
|
-
export const hydratedTransactionToPayloadBundle = (transaction: SignedHydratedTransactionWithHashMeta): PayloadBundle => {
|
|
9
|
-
const root = transaction[0]._hash
|
|
10
|
-
return bundle(root, transaction)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const bundle = (root: Hash, transaction: SignedHydratedTransactionWithHashMeta) => {
|
|
14
|
-
const payloads = flattenHydratedTransaction(transaction).flatMap(p => PayloadBuilder.omitStorageMeta(p))
|
|
15
|
-
return new PayloadBuilder<PayloadBundle>({ schema: PayloadBundleSchema })
|
|
16
|
-
.fields({ payloads, root })
|
|
17
|
-
.build()
|
|
18
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './BasePendingTransactions.ts'
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Address, asAddress, assertEx, filterAs, Hash,
|
|
3
|
-
isUndefined,
|
|
4
|
-
} from '@xylabs/sdk-js'
|
|
5
|
-
import { ArchivistInstance, ArchivistNextOptions } from '@xyo-network/archivist-model'
|
|
6
|
-
import {
|
|
7
|
-
analyzeChain, ChainStakeIntentAnalyzer,
|
|
8
|
-
isChainSummaryStakeIntent,
|
|
9
|
-
} from '@xyo-network/chain-analyze'
|
|
10
|
-
import {
|
|
11
|
-
DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS,
|
|
12
|
-
findFirstMatching, IntervalMap,
|
|
13
|
-
SerializedIntervalMap,
|
|
14
|
-
} from '@xyo-network/chain-utils'
|
|
15
|
-
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
16
|
-
import { Payload, WithStorageMeta } from '@xyo-network/payload-model'
|
|
17
|
-
import {
|
|
18
|
-
AbstractCreatableProvider,
|
|
19
|
-
asChainIndexingServiceStateWithStorageMeta,
|
|
20
|
-
BlockViewer,
|
|
21
|
-
BlockViewerMoniker,
|
|
22
|
-
ChainIndexingServiceState, ChainIndexingServiceStateSchema, ChainStakeViewer,
|
|
23
|
-
ChainStakeViewerMoniker,
|
|
24
|
-
creatableProvider,
|
|
25
|
-
isChainIndexingServiceState,
|
|
26
|
-
readPayloadMapFromStore,
|
|
27
|
-
StakeIntentService,
|
|
28
|
-
timeBudget,
|
|
29
|
-
} from '@xyo-network/xl1-sdk'
|
|
30
|
-
import {
|
|
31
|
-
asBlockBoundWitness, asBlockBoundWitnessWithStorageMeta, asChainStakeIntent, type Intent,
|
|
32
|
-
} from '@xyo-network/xl1-sdk'
|
|
33
|
-
import { Mutex } from 'async-mutex'
|
|
34
|
-
import { LRUCache } from 'lru-cache'
|
|
35
|
-
|
|
36
|
-
import { BaseServiceParams } from '../model/index.ts'
|
|
37
|
-
|
|
38
|
-
export interface XyoStakeIntentServiceParams extends BaseServiceParams {
|
|
39
|
-
blockViewer: BlockViewer
|
|
40
|
-
chainArchivist: ArchivistInstance
|
|
41
|
-
chainStakeViewer: ChainStakeViewer
|
|
42
|
-
stakeIntentStateArchivist: ArchivistInstance
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* The number of blocks to periodically persist state
|
|
47
|
-
*/
|
|
48
|
-
// const STATE_PERSISTENCE_INTERVAL = 60n
|
|
49
|
-
|
|
50
|
-
const ACTIVE_STAKE_TTL = 1000 * 60 * 60 * 2 // 2 hours in milliseconds
|
|
51
|
-
const NO_ACTIVE_STAKE_TTL = 1000 * 2 // 2 seconds in milliseconds
|
|
52
|
-
const STAKE_CACHE_MAX_ENTRIES = 10_000
|
|
53
|
-
|
|
54
|
-
@creatableProvider()
|
|
55
|
-
export class XyoStakeIntentService extends AbstractCreatableProvider<XyoStakeIntentServiceParams> implements StakeIntentService {
|
|
56
|
-
static readonly defaultMoniker = 'StakeIntent'
|
|
57
|
-
static readonly dependencies = []
|
|
58
|
-
static readonly monikers = [XyoStakeIntentService.defaultMoniker]
|
|
59
|
-
moniker = 'StakeIntent'
|
|
60
|
-
// TODO: Use hash instead of block number to handle chain reorgs
|
|
61
|
-
protected _lastIndexedBlockHash: Hash | undefined = undefined
|
|
62
|
-
// TODO: Interval tree per declaration (bank, validator, etc.)
|
|
63
|
-
|
|
64
|
-
// Ideally move to DataIntervalTree to handle declared
|
|
65
|
-
// ranges as it enables range queries in O(min(n, k * log n)) time,
|
|
66
|
-
// where k is the number of intervals in the output list time
|
|
67
|
-
// Currently using set based because it's simpler, equivalent
|
|
68
|
-
// in performance for small sets, and (most importantly) easily
|
|
69
|
-
// persisted so we can recover state on restart.
|
|
70
|
-
protected _producers: IntervalMap<Address> = new IntervalMap()
|
|
71
|
-
protected _stakeCache = new LRUCache<Address, bigint>({ max: STAKE_CACHE_MAX_ENTRIES })
|
|
72
|
-
protected _updateMutex = new Mutex()
|
|
73
|
-
|
|
74
|
-
private _blockViewer?: BlockViewer
|
|
75
|
-
private _chainStakeViewer?: ChainStakeViewer
|
|
76
|
-
|
|
77
|
-
protected get blockViewer() {
|
|
78
|
-
return this._blockViewer!
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
protected get chainArchivist() {
|
|
82
|
-
return assertEx(this.params.chainArchivist!, () => 'chainArchivist not set')
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
protected get chainStakeViewer() {
|
|
86
|
-
return this._chainStakeViewer!
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
protected get stakeIntentStateArchivist() {
|
|
90
|
-
return assertEx(this.params.stakeIntentStateArchivist!, () => 'stakeIntentStateArchivist not set')
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
static override async paramsHandler(params: Partial<XyoStakeIntentServiceParams>): Promise<XyoStakeIntentServiceParams> {
|
|
94
|
-
return {
|
|
95
|
-
...await super.paramsHandler(params),
|
|
96
|
-
chainArchivist: assertEx(params?.chainArchivist, () => 'chainArchivist is required'),
|
|
97
|
-
stakeIntentStateArchivist: assertEx(params?.stakeIntentStateArchivist, () => 'stakeIntentStateArchivist is required'),
|
|
98
|
-
} as XyoStakeIntentServiceParams
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
override async createHandler() {
|
|
102
|
-
this._blockViewer = await this.locator.getInstance(BlockViewerMoniker)
|
|
103
|
-
this._chainStakeViewer = await this.locator.getInstance(ChainStakeViewerMoniker)
|
|
104
|
-
const head = await this.blockViewer.currentBlock()
|
|
105
|
-
if (isUndefined(head)) return
|
|
106
|
-
await this.recoverState(head[0]._hash)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async getDeclaredCandidateRanges(address: Address, intent: Intent): Promise<Readonly<Readonly<[number, number]>[]>> {
|
|
110
|
-
await Promise.resolve()
|
|
111
|
-
assertEx(intent === 'producer', () => `Support not yet added for intent ${intent}`)
|
|
112
|
-
const results = this._producers.get(address)
|
|
113
|
-
return results ?? []
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async getDeclaredCandidatesForBlock(block: number, intent: Intent): Promise<Address[]> {
|
|
117
|
-
return await this.spanAsync('getDeclaredCandidatesForBlock', async () => {
|
|
118
|
-
assertEx(intent === 'producer', () => `Support not yet added for intent ${intent}`)
|
|
119
|
-
const results = this._producers.findAllContaining(block)
|
|
120
|
-
const candidates = [...results]
|
|
121
|
-
const requiredMinimumStake = this.getRequiredMinimumStakeForIntent(intent)
|
|
122
|
-
const validCandidates = await this.filterToValidStake(candidates, this.chainStakeViewer, requiredMinimumStake)
|
|
123
|
-
return validCandidates
|
|
124
|
-
}, this.context)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
getRequiredMinimumStakeForIntent(intent: Intent): bigint {
|
|
128
|
-
switch (intent) {
|
|
129
|
-
case 'producer': {
|
|
130
|
-
const { minStake } = this.params.context.config.actors.producer
|
|
131
|
-
return BigInt(minStake)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async isStakedForBlock(block: number, intent: Intent, address: Address): Promise<boolean> {
|
|
137
|
-
const candidates = await this.getDeclaredCandidatesForBlock(block, intent)
|
|
138
|
-
return candidates.includes(address)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
override async startHandler(): Promise<void> {
|
|
142
|
-
await this.updateIndex(true)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
private async filterToValidStake(
|
|
146
|
-
candidates: Address[],
|
|
147
|
-
chainStakeViewer: ChainStakeViewer,
|
|
148
|
-
requiredMinimumStake: bigint,
|
|
149
|
-
): Promise<Address[]> {
|
|
150
|
-
type CandidateStake = { candidate: Address; stake: bigint }
|
|
151
|
-
|
|
152
|
-
// Find the stake for each candidate
|
|
153
|
-
const candidatesWithStake: CandidateStake[] = await Promise.all(
|
|
154
|
-
candidates.map(async (candidate) => {
|
|
155
|
-
// Check if the stake is already cached
|
|
156
|
-
const stake = this._stakeCache.get(candidate)
|
|
157
|
-
if (stake === undefined) {
|
|
158
|
-
// Fetch from chainStakeViewer if not cached
|
|
159
|
-
const activeStake = await chainStakeViewer.activeByStaked(candidate)
|
|
160
|
-
if (activeStake > 0n) {
|
|
161
|
-
// Store result in cache
|
|
162
|
-
this._stakeCache.set(candidate, activeStake, { ttl: ACTIVE_STAKE_TTL })
|
|
163
|
-
} else {
|
|
164
|
-
this._stakeCache.set(candidate, activeStake, { ttl: NO_ACTIVE_STAKE_TTL })
|
|
165
|
-
}
|
|
166
|
-
return { candidate, stake: activeStake }
|
|
167
|
-
} else {
|
|
168
|
-
return { candidate, stake }
|
|
169
|
-
}
|
|
170
|
-
}),
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
// Filter out candidates whose stake is greater than or equal to the required minimum
|
|
174
|
-
return candidatesWithStake
|
|
175
|
-
.filter(({ stake }) => stake >= requiredMinimumStake)
|
|
176
|
-
.map(({ candidate }) => candidate)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
private async persistState(current: Hash): Promise<void> {
|
|
180
|
-
const state = this._producers.serialize()
|
|
181
|
-
const payload = new PayloadBuilder<ChainIndexingServiceState<SerializedIntervalMap>>({ schema: ChainIndexingServiceStateSchema })
|
|
182
|
-
.fields({ endBlockHash: current, state })
|
|
183
|
-
.build()
|
|
184
|
-
await this.stakeIntentStateArchivist.insert([payload])
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private async recoverState(current: Hash): Promise<void> {
|
|
188
|
-
return await timeBudget('XyoStakeIntentService.recoverState', console, async () => {
|
|
189
|
-
const currentBlock = assertEx(asBlockBoundWitness((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`)
|
|
190
|
-
const currentBlockNum = currentBlock.block
|
|
191
|
-
// Find last state before current head (in case of rollback, we indexed past it on an uncle chain, etc.)
|
|
192
|
-
const opts: ArchivistNextOptions = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS }
|
|
193
|
-
while (true) {
|
|
194
|
-
const predicate = (p: WithStorageMeta<Payload>) => {
|
|
195
|
-
const state = asChainIndexingServiceStateWithStorageMeta(p)
|
|
196
|
-
return state ? true : false
|
|
197
|
-
}
|
|
198
|
-
const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts)
|
|
199
|
-
if (isChainIndexingServiceState<SerializedIntervalMap>(state)) {
|
|
200
|
-
const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0]
|
|
201
|
-
const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed)
|
|
202
|
-
if (indexedBlock) {
|
|
203
|
-
const indexedBlockNum = indexedBlock.block
|
|
204
|
-
if (indexedBlockNum <= currentBlockNum) {
|
|
205
|
-
const data = state.state as SerializedIntervalMap
|
|
206
|
-
this._producers = new IntervalMap(data)
|
|
207
|
-
this._lastIndexedBlockHash = indexedBlock._hash
|
|
208
|
-
break
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
// No state found, start from genesis
|
|
213
|
-
break
|
|
214
|
-
}
|
|
215
|
-
opts.open = true
|
|
216
|
-
}
|
|
217
|
-
}, 2000, true)
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
private async updateIndex(displayProgress = false): Promise<void> {
|
|
221
|
-
if (this._updateMutex.isLocked()) {
|
|
222
|
-
return
|
|
223
|
-
}
|
|
224
|
-
await this._updateMutex.runExclusive(async () => {
|
|
225
|
-
return await this.spanAsync('updateIndex', async () => {
|
|
226
|
-
const currentHead = (await this.blockViewer.currentBlock())[0]
|
|
227
|
-
if (isUndefined(currentHead)) return
|
|
228
|
-
const currentHeadHash = currentHead._hash
|
|
229
|
-
const chainMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.chainArchivist)
|
|
230
|
-
const result = await analyzeChain(
|
|
231
|
-
{ ...this.context, chainMap },
|
|
232
|
-
[new ChainStakeIntentAnalyzer('producer')],
|
|
233
|
-
currentHeadHash,
|
|
234
|
-
this._lastIndexedBlockHash,
|
|
235
|
-
)
|
|
236
|
-
const signedDeclarations = filterAs(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent)
|
|
237
|
-
if (currentHead.block === undefined) return
|
|
238
|
-
const currentHeadBlockNum = currentHead.block
|
|
239
|
-
if (displayProgress) this.logger?.log(`Updating index through 0x${currentHeadBlockNum}`)
|
|
240
|
-
for (const signedDeclaration of signedDeclarations) {
|
|
241
|
-
const { exp, nbf } = signedDeclaration
|
|
242
|
-
const start = nbf
|
|
243
|
-
const stop = exp
|
|
244
|
-
const address = asAddress(signedDeclaration?.from)
|
|
245
|
-
if (start !== undefined && stop !== undefined && address !== undefined) {
|
|
246
|
-
this._producers.insert(address, start, stop)
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
/*
|
|
250
|
-
if (index % STATE_PERSISTENCE_INTERVAL === 0n) {
|
|
251
|
-
if (displayProgress) this.logger?.info(`Persisting state at block ${index}`)
|
|
252
|
-
await this.persistState(await PayloadBuilder.hash(block))
|
|
253
|
-
}
|
|
254
|
-
*/
|
|
255
|
-
this._lastIndexedBlockHash = currentHeadHash
|
|
256
|
-
}, this.context)
|
|
257
|
-
})
|
|
258
|
-
}
|
|
259
|
-
}
|
package/src/StakeIntent/index.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { Hash } from '@xylabs/sdk-js'
|
|
2
|
-
import { exists, filterAs } from '@xylabs/sdk-js'
|
|
3
|
-
import type { ArchivistInstance } from '@xyo-network/archivist-model'
|
|
4
|
-
import type { BoundWitness } from '@xyo-network/boundwitness-model'
|
|
5
|
-
import { isBoundWitness } from '@xyo-network/boundwitness-model'
|
|
6
|
-
import { payloadSchemasContains } from '@xyo-network/boundwitness-validator'
|
|
7
|
-
import { BoundWitnessWrapper } from '@xyo-network/boundwitness-wrapper'
|
|
8
|
-
import type {
|
|
9
|
-
BlockBoundWitness, ChainStakeIntent, Intent,
|
|
10
|
-
} from '@xyo-network/xl1-sdk'
|
|
11
|
-
import { asChainStakeIntent, ChainStakeIntentSchema } from '@xyo-network/xl1-sdk'
|
|
12
|
-
|
|
13
|
-
export const getBlockSignedStakeDeclarations = async (block: BlockBoundWitness, archivist: ArchivistInstance, intent: Intent): Promise<ChainStakeIntent[]> => {
|
|
14
|
-
// Get payloads in block
|
|
15
|
-
const blockData = await archivist.get(block.payload_hashes)
|
|
16
|
-
// Filter Payloads in block to BoundWitnesses
|
|
17
|
-
const bwsFromBlock = blockData.filter(x => isBoundWitness(x))
|
|
18
|
-
// Filter to BoundWitnesses with StakeIntent payloads
|
|
19
|
-
const bwsFromBlockWithDeclarations = bwsFromBlock.filter(bw => payloadSchemasContains(bw, ChainStakeIntentSchema))
|
|
20
|
-
// Filter to only valid signed BWs
|
|
21
|
-
const validBlockBwsWithDeclarations = await filterToValidSignedBoundWitnesses(bwsFromBlockWithDeclarations)
|
|
22
|
-
return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {
|
|
23
|
-
// Get staked intent hashes from signed declarations
|
|
24
|
-
const stakeIntentHashes = validBlockBwsWithDeclarations
|
|
25
|
-
.flatMap(mapBoundWitnessToStakeIntentHashes)
|
|
26
|
-
.filter(exists)
|
|
27
|
-
// Get staked intent payloads
|
|
28
|
-
const payloads = await archivist.get(stakeIntentHashes)
|
|
29
|
-
// Filter payloads to staked intents
|
|
30
|
-
const stakeIntents = filterAs(payloads, asChainStakeIntent)
|
|
31
|
-
// that are producers
|
|
32
|
-
.filter(p => p.intent === intent)
|
|
33
|
-
// where the issuer of the intent is also the signer of this BW
|
|
34
|
-
.filter(p => bw.addresses.includes(p.from))
|
|
35
|
-
|
|
36
|
-
return stakeIntents
|
|
37
|
-
}))).flat()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const filterToValidSignedBoundWitnesses = async (bws: BoundWitness[]): Promise<BoundWitness[]> => {
|
|
41
|
-
const validBwIndexes = await Promise.all(bws.map(bw => BoundWitnessWrapper.parse(bw).getValid()))
|
|
42
|
-
return bws.filter((_, index) => validBwIndexes[index])
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const mapBoundWitnessToStakeIntentHashes = (bw: BoundWitness): (Hash | undefined)[] => {
|
|
46
|
-
return bw.payload_schemas.map((schema, index) => schema === ChainStakeIntentSchema ? bw.payload_hashes[index] : undefined)
|
|
47
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './getBlockSignedStakeDeclarations.ts'
|