@clayno-club/asset-flow 0.1.3 → 0.1.4

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 CHANGED
@@ -1,14 +1,19 @@
1
1
  # @clayno-club/asset-flow
2
2
 
3
- Deterministic Solana NFT asset-flow classification and normalization.
3
+ Deterministic asset-flow classification and normalization for supported chains.
4
4
 
5
- This package turns transaction data into a canonical ownership history for a mint. It is designed for consumers that want consistent classification results across services, codebases, or audit pipelines.
5
+ This package turns transaction data into a canonical ownership history for a tracked asset. It is designed for consumers that want consistent classification results across services, codebases, or audit pipelines.
6
+
7
+ Current support:
8
+
9
+ - Solana NFT asset-flow normalization via the root convenience exports such as `classify`, `buildFlows`, and `buildOwnershipPeriods`
10
+ - Sui Popkins classification via explicit Sui exports such as `classifySuiTransactionForAsset`
6
11
 
7
12
  ## What it does
8
13
 
9
- - classify enhanced Solana transactions for a tracked mint
10
- - merge raw ownership evidence into enhanced transactions when needed
11
- - normalize a mint's transaction history into canonical flows
14
+ - classify supported chain transactions for a tracked asset
15
+ - merge raw ownership evidence into enhanced Solana transactions when needed
16
+ - normalize an asset's transaction history into canonical flows
12
17
  - derive ownership periods from normalized flows
13
18
  - explain why a transaction matched a given classification path
14
19
  - analyze provided transaction sets for review candidates
@@ -21,6 +26,11 @@ This package turns transaction data into a canonical ownership history for a min
21
26
 
22
27
  You provide the transaction data. The package provides deterministic interpretation.
23
28
 
29
+ ## Supported entrypoints
30
+
31
+ - Root exports: Solana-oriented convenience API such as `classify`, `buildMintHistory`, `buildFlows`, `buildValueMovements`, and `augmentWithRaw`
32
+ - Sui exports: explicit helpers such as `classifySuiTransactionForAsset` and the Sui transaction/type definitions
33
+
24
34
  ## Install
25
35
 
26
36
  ```bash
package/dist/index.d.ts CHANGED
@@ -152,6 +152,53 @@ interface NormalizedMintHistory {
152
152
  periods: ReconstructedOwnershipPeriod[];
153
153
  }
154
154
 
155
+ declare function classifyEnhancedTransactionForMint(tx: HeliusEnhancedTx, mint: string): AssetFlowTxClassification;
156
+
157
+ interface AssetFlowCoverageReviewCandidate {
158
+ mint: string;
159
+ signature: string;
160
+ timestamp: number | null;
161
+ source: string;
162
+ normalizedType: string;
163
+ matcherId: string;
164
+ family: AssetFlowTxClassification["family"];
165
+ effect: AssetFlowTxClassification["effect"];
166
+ materialization: AssetFlowTxClassification["materialization"];
167
+ confidence: AssetFlowTxClassification["confidence"];
168
+ reason: AssetFlowTxClassification["reason"];
169
+ hasOwnershipChange: boolean;
170
+ hasMeaningfulSettlement: boolean;
171
+ programIds: string[];
172
+ instructionLabels: string[];
173
+ }
174
+ interface AssetFlowCoverageCluster {
175
+ fingerprint: string;
176
+ matcherId: string;
177
+ family: AssetFlowTxClassification["family"];
178
+ effect: AssetFlowTxClassification["effect"];
179
+ materialization: AssetFlowTxClassification["materialization"];
180
+ confidence: AssetFlowTxClassification["confidence"];
181
+ normalizedType: string;
182
+ source: string;
183
+ reason: AssetFlowTxClassification["reason"];
184
+ hasOwnershipChange: boolean;
185
+ hasMeaningfulSettlement: boolean;
186
+ programIds: string[];
187
+ instructionLabels: string[];
188
+ count: number;
189
+ sampleSignatures: string[];
190
+ sampleMints: string[];
191
+ }
192
+ interface AssetFlowCoverageScanResult {
193
+ mint: string;
194
+ transactionsScanned: number;
195
+ reviewCandidates: AssetFlowCoverageReviewCandidate[];
196
+ clusters: AssetFlowCoverageCluster[];
197
+ }
198
+ declare function collectCoverageReviewCandidates(transactions: HeliusEnhancedTx[], mint: string): AssetFlowCoverageReviewCandidate[];
199
+ declare function clusterCoverageReviewCandidates(candidates: AssetFlowCoverageReviewCandidate[], sampleLimit?: number): AssetFlowCoverageCluster[];
200
+ declare function scanTransactionsForCoverage(transactions: HeliusEnhancedTx[], mint: string): AssetFlowCoverageScanResult;
201
+
155
202
  type AssetOwnershipKind = "NONE" | "DIRECT" | "CUSTODY" | "SAME_OWNER" | "AMBIGUOUS";
156
203
  type AssetSettlementKind = "NONE" | "NATIVE_SALE" | "POTENTIAL_SALE" | "AMBIGUOUS";
157
204
  type AssetNftTouchKind = "NONE" | "SAME_OWNER" | "OWNERSHIP_CHANGE";
@@ -175,20 +222,6 @@ interface AssetFlowTransactionFacts {
175
222
  instructionLabels: string[];
176
223
  }
177
224
 
178
- declare function buildTransactionFacts(tx: HeliusEnhancedTx, mint: string): AssetFlowTransactionFacts;
179
-
180
- declare function normalizeEnhancedType(value: string | undefined): string;
181
- declare function toNullableNumber(value: unknown): number | null;
182
- declare function isNonFungibleTokenStandard(tokenStandard: string | null | undefined): boolean;
183
- declare function isMintNftTransfer(transfer: HeliusTokenTransfer, mint: string): boolean;
184
- declare function getMintNftTransfers(tx: HeliusEnhancedTx, mint: string): HeliusTokenTransfer[];
185
- declare function hasMeaningfulNativeSettlement(tx: HeliusEnhancedTx, mint: string): boolean;
186
-
187
- declare function observationFromFacts(facts: AssetFlowTransactionFacts): AssetFlowObservation;
188
- declare function observeEnhancedTransactionForMint(tx: HeliusEnhancedTx, mint: string): AssetFlowObservation;
189
-
190
- declare function classifyEnhancedTransactionForMint(tx: HeliusEnhancedTx, mint: string): AssetFlowTxClassification;
191
-
192
225
  interface AssetFlowClassificationMatcher {
193
226
  id: string;
194
227
  matches(observation: AssetFlowObservation): boolean;
@@ -211,50 +244,28 @@ interface AssetFlowClassificationExplanation {
211
244
  }
212
245
  declare function explainEnhancedTransactionForMint(tx: HeliusEnhancedTx, mint: string): AssetFlowClassificationExplanation;
213
246
 
214
- interface AssetFlowCoverageReviewCandidate {
215
- mint: string;
216
- signature: string;
217
- timestamp: number | null;
218
- source: string;
219
- normalizedType: string;
220
- matcherId: string;
221
- family: AssetFlowTxClassification["family"];
222
- effect: AssetFlowTxClassification["effect"];
223
- materialization: AssetFlowTxClassification["materialization"];
224
- confidence: AssetFlowTxClassification["confidence"];
225
- reason: AssetFlowTxClassification["reason"];
226
- hasOwnershipChange: boolean;
227
- hasMeaningfulSettlement: boolean;
228
- programIds: string[];
229
- instructionLabels: string[];
230
- }
231
- interface AssetFlowCoverageCluster {
232
- fingerprint: string;
247
+ declare function buildTransactionFacts(tx: HeliusEnhancedTx, mint: string): AssetFlowTransactionFacts;
248
+
249
+ interface ClassificationInput {
250
+ family: AssetFlowFamily;
251
+ derivedType: AssetFlowDerivedType;
233
252
  matcherId: string;
234
- family: AssetFlowTxClassification["family"];
235
- effect: AssetFlowTxClassification["effect"];
236
- materialization: AssetFlowTxClassification["materialization"];
237
- confidence: AssetFlowTxClassification["confidence"];
238
- normalizedType: string;
239
- source: string;
240
- reason: AssetFlowTxClassification["reason"];
241
- hasOwnershipChange: boolean;
242
- hasMeaningfulSettlement: boolean;
243
- programIds: string[];
244
- instructionLabels: string[];
245
- count: number;
246
- sampleSignatures: string[];
247
- sampleMints: string[];
248
- }
249
- interface AssetFlowCoverageScanResult {
250
- mint: string;
251
- transactionsScanned: number;
252
- reviewCandidates: AssetFlowCoverageReviewCandidate[];
253
- clusters: AssetFlowCoverageCluster[];
253
+ reason: string;
254
+ observation: {
255
+ normalizedType: string;
256
+ hasOwnershipChange: boolean;
257
+ };
258
+ overrides?: Partial<Pick<AssetFlowTxClassification, "normalizedType" | "effect" | "materialization" | "confidence" | "shouldExtractValueMovements">>;
254
259
  }
255
- declare function collectCoverageReviewCandidates(transactions: HeliusEnhancedTx[], mint: string): AssetFlowCoverageReviewCandidate[];
256
- declare function clusterCoverageReviewCandidates(candidates: AssetFlowCoverageReviewCandidate[], sampleLimit?: number): AssetFlowCoverageCluster[];
257
- declare function scanTransactionsForCoverage(transactions: HeliusEnhancedTx[], mint: string): AssetFlowCoverageScanResult;
260
+ declare const PERSIST_DERIVED_TYPES: Set<AssetFlowDerivedType>;
261
+ declare function classification(input: ClassificationInput): AssetFlowTxClassification;
262
+
263
+ declare const protocolMatchers: RegisteredAssetFlowClassificationMatcher[];
264
+ declare const coreAndMarketplaceMatchers: RegisteredAssetFlowClassificationMatcher[];
265
+ declare const assetFlowMatchers: RegisteredAssetFlowClassificationMatcher[];
266
+
267
+ declare function getMatchingAssetFlowMatchers(matchers: RegisteredAssetFlowClassificationMatcher[], observation: AssetFlowObservation): RegisteredAssetFlowClassificationMatcher[];
268
+ declare function selectAssetFlowMatcher(matchers: RegisteredAssetFlowClassificationMatcher[], observation: AssetFlowObservation): RegisteredAssetFlowClassificationMatcher;
258
269
 
259
270
  declare function reconstructOwnershipPeriods(flows: ExtractedMintFlow[]): ReconstructedOwnershipPeriod[];
260
271
 
@@ -263,6 +274,30 @@ declare function extractMintFlows(transactions: HeliusEnhancedTx[], mint: string
263
274
  declare function extractValueMovements(transactions: HeliusEnhancedTx[], mint: string, classificationCache?: Map<string, AssetFlowTxClassification>): ExtractedValueMovement[];
264
275
  declare function normalizeMintHistory(transactions: HeliusEnhancedTx[], mint: string): NormalizedMintHistory;
265
276
 
277
+ declare function observationFromFacts(facts: AssetFlowTransactionFacts): AssetFlowObservation;
278
+ declare function observeEnhancedTransactionForMint(tx: HeliusEnhancedTx, mint: string): AssetFlowObservation;
279
+
280
+ type MintFlowProtocolEventKind = "DIRECT_FLOW" | "POOL_SALE" | "ESCROW_SALE" | "SWAP_REASSIGN";
281
+ interface MintFlowProtocolEventFlow {
282
+ fromAddress: string | null;
283
+ toAddress: string | null;
284
+ transferIndex: number;
285
+ tokenStandard: string | null;
286
+ derivedType: ExtractedMintFlow["derivedType"];
287
+ }
288
+ interface MintFlowProtocolEvent {
289
+ kind: MintFlowProtocolEventKind;
290
+ tx: HeliusEnhancedTx;
291
+ timestamp: number;
292
+ classification: AssetFlowTxClassification | null;
293
+ flows: MintFlowProtocolEventFlow[];
294
+ }
295
+ declare function interpretMintFlowProtocolEvent(params: {
296
+ tx: HeliusEnhancedTx;
297
+ mint: string;
298
+ getClassification: (tx: HeliusEnhancedTx) => AssetFlowTxClassification;
299
+ }): MintFlowProtocolEvent | null;
300
+
266
301
  declare function extractCandidateMintsFromRawTransaction(tx: RawAssetFlowTransaction): string[];
267
302
  declare function synthesizeEnhancedTransactionsFromRaw(tx: RawAssetFlowTransaction): HeliusEnhancedTx[];
268
303
  declare function mergeRawProgramEvidence(tx: HeliusEnhancedTx, rawTx: RawAssetFlowTransaction): HeliusEnhancedTx;
@@ -271,4 +306,78 @@ declare function augmentEnhancedTransactionWithRaw(tx: HeliusEnhancedTx, rawTx:
271
306
  declare function applyRawOwnerOverridesToEnhanced(tx: HeliusEnhancedTx, rawTx: RawAssetFlowTransaction): HeliusEnhancedTx;
272
307
  declare function shouldFetchRawForMintTx(tx: HeliusEnhancedTx, mint: string): boolean;
273
308
 
274
- export { type AssetFlowClassificationExplanation, type AssetFlowCoverageCluster, type AssetFlowCoverageReviewCandidate, type AssetFlowCoverageScanResult, type AssetFlowDerivedType, type AssetFlowEffect, type AssetFlowFamily, type AssetFlowInterpreterConfidence, type AssetFlowMatcherExplanation, type AssetFlowMaterialization, type AssetFlowObservation, type AssetFlowTransactionFacts, type AssetFlowTxClassification, type AssetNftTouchKind, type AssetOwnershipKind, type AssetSettlementKind, type ExtractedMintFlow, type ExtractedValueMovement, type HeliusEnhancedAction, type HeliusEnhancedInstruction, type HeliusEnhancedTx, type HeliusNativeTransfer, type HeliusTokenTransfer, type NormalizedMintHistory, type RawAssetFlowAccountKey, type RawAssetFlowInstruction, type RawAssetFlowTokenBalance, type RawAssetFlowTransaction, type ReconstructedOwnershipPeriod, applyRawOwnerOverridesToEnhanced, augmentEnhancedTransactionWithRaw, augmentEnhancedTransactionWithRaw as augmentWithRaw, extractMintFlows as buildFlows, normalizeMintHistory as buildMintHistory, reconstructOwnershipPeriods as buildOwnershipPeriods, buildTransactionFacts, extractValueMovements as buildValueMovements, classifyEnhancedTransactionForMint as classify, classifyEnhancedTransactionForMint, clusterCoverageReviewCandidates, collectCoverageReviewCandidates, explainEnhancedTransactionForMint as explain, explainEnhancedTransactionForMint, extractCandidateMintsFromEnhancedTx, extractCandidateMintsFromRawTransaction, extractMintFlows, extractCandidateMintsFromEnhancedTx as extractMints, extractValueMovements, getMintNftTransfers, hasMeaningfulNativeSettlement, isMintNftTransfer, isNonFungibleTokenStandard, mergeRawProgramEvidence, normalizeEnhancedType, normalizeMintHistory, observationFromFacts, observeEnhancedTransactionForMint, reconstructOwnershipPeriods, scanTransactionsForCoverage, shouldApplyRawOwnerOverrides, shouldFetchRawForMintTx as shouldFetchRaw, shouldFetchRawForMintTx, synthesizeEnhancedTransactionsFromRaw, toNullableNumber };
309
+ declare function normalizeEnhancedType(value: string | undefined): string;
310
+ declare function toNullableNumber(value: unknown): number | null;
311
+ declare function isNonFungibleTokenStandard(tokenStandard: string | null | undefined): boolean;
312
+ declare function isMintNftTransfer(transfer: HeliusTokenTransfer, mint: string): boolean;
313
+ declare function getMintNftTransfers(tx: HeliusEnhancedTx, mint: string): HeliusTokenTransfer[];
314
+ declare function hasMeaningfulNativeSettlement(tx: HeliusEnhancedTx, mint: string): boolean;
315
+
316
+ interface SuiEventLike {
317
+ type: string;
318
+ parsedJson?: unknown | null;
319
+ }
320
+ type SuiObjectOwnerLike = {
321
+ AddressOwner: string;
322
+ } | {
323
+ ObjectOwner: string;
324
+ } | {
325
+ Shared: {
326
+ initial_shared_version: string;
327
+ };
328
+ } | {
329
+ ConsensusV2: unknown;
330
+ } | "Immutable" | null | undefined;
331
+ interface SuiObjectChangeLike {
332
+ type: string;
333
+ objectId?: string;
334
+ objectType?: string;
335
+ sender?: string;
336
+ owner?: SuiObjectOwnerLike;
337
+ recipient?: SuiObjectOwnerLike;
338
+ }
339
+ interface SuiBalanceChangeLike {
340
+ owner?: SuiObjectOwnerLike;
341
+ coinType?: string;
342
+ amount?: string;
343
+ }
344
+ interface SuiTransactionBlockLike {
345
+ digest: string;
346
+ checkpoint?: string | null;
347
+ timestampMs?: string | null;
348
+ events?: SuiEventLike[] | null;
349
+ objectChanges?: SuiObjectChangeLike[] | null;
350
+ balanceChanges?: SuiBalanceChangeLike[] | null;
351
+ transaction?: {
352
+ data?: {
353
+ sender?: string | null;
354
+ } | null;
355
+ } | null;
356
+ }
357
+ type SuiAssetFlowFamily = "NFT_MINT" | "TRADEPORT_SALE" | "TRADEPORT_LISTING" | "TRADEPORT_BID_INTENT" | "POPKINS_STAKING" | "POPSWAP" | "GENERIC_OBJECT_TRANSFER" | "UNKNOWN";
358
+ interface SuiAssetOwnerChange {
359
+ sender: string | null;
360
+ nextOwner: string | null;
361
+ objectType: string | null;
362
+ }
363
+ interface SuiAssetFlowClassification {
364
+ assetId: string;
365
+ family: SuiAssetFlowFamily;
366
+ effect: AssetFlowEffect;
367
+ materialization: AssetFlowMaterialization;
368
+ confidence: AssetFlowInterpreterConfidence;
369
+ derivedType: AssetFlowDerivedType;
370
+ matcherId: string;
371
+ reason: string;
372
+ hasOwnershipChange: boolean;
373
+ shouldExtractValueMovements: boolean;
374
+ eventTypes: string[];
375
+ market: string | null;
376
+ priceRaw: string | null;
377
+ currency: string | null;
378
+ ownerChange: SuiAssetOwnerChange | null;
379
+ }
380
+
381
+ declare function classifySuiTransactionForAsset(tx: SuiTransactionBlockLike, assetId: string): SuiAssetFlowClassification;
382
+
383
+ export { type AssetFlowClassificationExplanation, type AssetFlowClassificationMatcher, type AssetFlowCoverageCluster, type AssetFlowCoverageReviewCandidate, type AssetFlowCoverageScanResult, type AssetFlowDerivedType, type AssetFlowEffect, type AssetFlowFamily, type AssetFlowInterpreterConfidence, type AssetFlowMatcherExplanation, type AssetFlowMaterialization, type AssetFlowObservation, type AssetFlowTransactionFacts, type AssetFlowTxClassification, type AssetNftTouchKind, type AssetOwnershipKind, type AssetSettlementKind, type ExtractedMintFlow, type ExtractedValueMovement, type HeliusEnhancedAction, type HeliusEnhancedInstruction, type HeliusEnhancedTx, type HeliusNativeTransfer, type HeliusTokenTransfer, type MintFlowProtocolEvent, type MintFlowProtocolEventFlow, type MintFlowProtocolEventKind, type NormalizedMintHistory, PERSIST_DERIVED_TYPES, type RawAssetFlowAccountKey, type RawAssetFlowInstruction, type RawAssetFlowTokenBalance, type RawAssetFlowTransaction, type ReconstructedOwnershipPeriod, type RegisteredAssetFlowClassificationMatcher, type SuiAssetFlowClassification, type SuiAssetFlowFamily, type SuiAssetOwnerChange, type SuiBalanceChangeLike, type SuiEventLike, type SuiObjectChangeLike, type SuiObjectOwnerLike, type SuiTransactionBlockLike, applyRawOwnerOverridesToEnhanced, assetFlowMatchers, augmentEnhancedTransactionWithRaw, augmentEnhancedTransactionWithRaw as augmentWithRaw, extractMintFlows as buildFlows, normalizeMintHistory as buildMintHistory, reconstructOwnershipPeriods as buildOwnershipPeriods, buildTransactionFacts, extractValueMovements as buildValueMovements, classification, classifyEnhancedTransactionForMint as classify, classifyEnhancedTransactionForMint, classifySuiTransactionForAsset, clusterCoverageReviewCandidates, collectCoverageReviewCandidates, coreAndMarketplaceMatchers, explainEnhancedTransactionForMint as explain, explainEnhancedTransactionForMint, extractCandidateMintsFromEnhancedTx, extractCandidateMintsFromRawTransaction, extractMintFlows, extractCandidateMintsFromEnhancedTx as extractMints, extractValueMovements, getMatchingAssetFlowMatchers, getMintNftTransfers, hasMeaningfulNativeSettlement, interpretMintFlowProtocolEvent, isMintNftTransfer, isNonFungibleTokenStandard, mergeRawProgramEvidence, normalizeEnhancedType, normalizeMintHistory, observationFromFacts, observeEnhancedTransactionForMint, protocolMatchers, reconstructOwnershipPeriods, scanTransactionsForCoverage, selectAssetFlowMatcher, shouldApplyRawOwnerOverrides, shouldFetchRawForMintTx as shouldFetchRaw, shouldFetchRawForMintTx, synthesizeEnhancedTransactionsFromRaw, toNullableNumber };