Skip to content

Commit 5a52d5c

Browse files
committed
feat: add transaction projection indexed by credentials
1 parent 367683d commit 5a52d5c

File tree

19 files changed

+663
-108
lines changed

19 files changed

+663
-108
lines changed

packages/cardano-services/src/Projection/prepareTypeormProjection.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
AssetEntity,
44
BlockDataEntity,
55
BlockEntity,
6+
CredentialEntity,
67
CurrentPoolMetricsEntity,
78
DataSourceExtensions,
89
GovernanceActionEntity,
@@ -18,22 +19,26 @@ import {
1819
StakeKeyRegistrationEntity,
1920
StakePoolEntity,
2021
TokensEntity,
22+
TransactionEntity,
2123
createStorePoolMetricsUpdateJob,
2224
createStoreStakePoolMetadataJob,
2325
storeAddresses,
2426
storeAssets,
2527
storeBlock,
28+
storeCredentials,
2629
storeGovernanceAction,
2730
storeHandleMetadata,
2831
storeHandles,
2932
storeNftMetadata,
3033
storeStakeKeyRegistrations,
3134
storeStakePoolRewardsJob,
3235
storeStakePools,
36+
storeTransactions,
3337
storeUtxo,
3438
willStoreAddresses,
3539
willStoreAssets,
3640
willStoreBlockData,
41+
willStoreCredentials,
3742
willStoreGovernanceAction,
3843
willStoreHandleMetadata,
3944
willStoreHandles,
@@ -42,6 +47,7 @@ import {
4247
willStoreStakePoolMetadataJob,
4348
willStoreStakePoolRewardsJob,
4449
willStoreStakePools,
50+
willStoreTransactions,
4551
willStoreUtxo
4652
} from '@cardano-sdk/projection-typeorm';
4753
import { Cardano, ChainSyncEventType } from '@cardano-sdk/core';
@@ -61,6 +67,7 @@ export enum ProjectionName {
6167
StakePoolMetadataJob = 'stake-pool-metadata-job',
6268
StakePoolMetricsJob = 'stake-pool-metrics-job',
6369
StakePoolRewardsJob = 'stake-pool-rewards-job',
70+
Transaction = 'transaction',
6471
UTXO = 'utxo'
6572
}
6673

@@ -105,7 +112,8 @@ const createMapperOperators = (
105112
withNftMetadata: Mapper.withNftMetadata({ logger }),
106113
withStakeKeyRegistrations: Mapper.withStakeKeyRegistrations(),
107114
withStakePools: Mapper.withStakePools(),
108-
withUtxo: Mapper.withUtxo()
115+
withUtxo: Mapper.withUtxo(),
116+
withValidByronAddresses: Mapper.withValidByronAddresses()
109117
};
110118
};
111119
type MapperOperators = ReturnType<typeof createMapperOperators>;
@@ -116,6 +124,7 @@ export const storeOperators = {
116124
storeAddresses: storeAddresses(),
117125
storeAssets: storeAssets(),
118126
storeBlock: storeBlock(),
127+
storeCredentials: storeCredentials(),
119128
storeGovernanceAction: storeGovernanceAction(),
120129
storeHandleMetadata: storeHandleMetadata(),
121130
storeHandles: storeHandles(),
@@ -128,6 +137,7 @@ export const storeOperators = {
128137
storeStakePoolMetadataJob: createStoreStakePoolMetadataJob()(),
129138
storeStakePoolRewardsJob: storeStakePoolRewardsJob(),
130139
storeStakePools: storeStakePools(),
140+
storeTransactions: storeTransactions(),
131141
storeUtxo: storeUtxo()
132142
};
133143
type StoreOperators = typeof storeOperators;
@@ -143,6 +153,7 @@ type WillStore = {
143153
const willStore: Partial<WillStore> = {
144154
storeAddresses: willStoreAddresses,
145155
storeAssets: willStoreAssets,
156+
storeCredentials: willStoreCredentials,
146157
storeGovernanceAction: willStoreGovernanceAction,
147158
storeHandleMetadata: willStoreHandleMetadata,
148159
storeHandles: willStoreHandles,
@@ -151,6 +162,7 @@ const willStore: Partial<WillStore> = {
151162
storeStakePoolMetadataJob: willStoreStakePoolMetadataJob,
152163
storeStakePoolRewardsJob: willStoreStakePoolRewardsJob,
153164
storeStakePools: willStoreStakePools,
165+
storeTransactions: willStoreTransactions,
154166
storeUtxo: willStoreUtxo
155167
};
156168

@@ -159,6 +171,7 @@ const entities = {
159171
asset: AssetEntity,
160172
block: BlockEntity,
161173
blockData: BlockDataEntity,
174+
credential: CredentialEntity,
162175
currentPoolMetrics: CurrentPoolMetricsEntity,
163176
governanceAction: GovernanceActionEntity,
164177
handle: HandleEntity,
@@ -172,7 +185,8 @@ const entities = {
172185
poolRewards: PoolRewardsEntity,
173186
stakeKeyRegistration: StakeKeyRegistrationEntity,
174187
stakePool: StakePoolEntity,
175-
tokens: TokensEntity
188+
tokens: TokensEntity,
189+
transaction: TransactionEntity
176190
};
177191
export const allEntities = Object.values(entities);
178192
type Entities = typeof entities;
@@ -183,6 +197,7 @@ const storeEntities: Partial<Record<StoreName, EntityName[]>> = {
183197
storeAddresses: ['address'],
184198
storeAssets: ['asset'],
185199
storeBlock: ['block', 'blockData'],
200+
storeCredentials: ['credential', 'transaction', 'output'],
186201
storeGovernanceAction: ['governanceAction'],
187202
storeHandleMetadata: ['handleMetadata', 'output'],
188203
storeHandles: ['handle', 'asset', 'tokens', 'output'],
@@ -194,13 +209,15 @@ const storeEntities: Partial<Record<StoreName, EntityName[]>> = {
194209
storeStakePoolMetadataJob: ['stakePool', 'currentPoolMetrics', 'poolMetadata'],
195210
storeStakePoolRewardsJob: ['poolRewards', 'stakePool'],
196211
storeStakePools: ['stakePool', 'currentPoolMetrics', 'poolMetadata', 'poolDelisted'],
212+
storeTransactions: ['block', 'transaction'],
197213
storeUtxo: ['tokens', 'output']
198214
};
199215

200216
const entityInterDependencies: Partial<Record<EntityName, EntityName[]>> = {
201217
address: ['stakeKeyRegistration'],
202218
asset: ['block', 'nftMetadata'],
203219
blockData: ['block'],
220+
credential: [],
204221
currentPoolMetrics: ['stakePool'],
205222
governanceAction: ['block'],
206223
handle: ['asset'],
@@ -212,7 +229,8 @@ const entityInterDependencies: Partial<Record<EntityName, EntityName[]>> = {
212229
poolRetirement: ['block'],
213230
stakeKeyRegistration: ['block'],
214231
stakePool: ['block', 'poolRegistration', 'poolRetirement'],
215-
tokens: ['asset']
232+
tokens: ['asset'],
233+
transaction: ['block', 'credential']
216234
};
217235

218236
export const getEntities = (entityNames: EntityName[]): Entity[] => {
@@ -244,12 +262,14 @@ const mapperInterDependencies: Partial<Record<MapperName, MapperName[]>> = {
244262
withHandles: ['withMint', 'filterMint', 'withUtxo', 'filterUtxo', 'withCIP67'],
245263
withNftMetadata: ['withCIP67', 'withMint', 'filterMint'],
246264
withStakeKeyRegistrations: ['withCertificates'],
247-
withStakePools: ['withCertificates']
265+
withStakePools: ['withCertificates'],
266+
withValidByronAddresses: ['withUtxo']
248267
};
249268

250269
const storeMapperDependencies: Partial<Record<StoreName, MapperName[]>> = {
251270
storeAddresses: ['withAddresses'],
252271
storeAssets: ['withMint'],
272+
storeCredentials: ['withAddresses', 'withCertificates', 'withUtxo', 'withValidByronAddresses'],
253273
storeHandleMetadata: ['withHandleMetadata'],
254274
storeHandles: ['withHandles'],
255275
storeNftMetadata: ['withNftMetadata'],
@@ -270,6 +290,7 @@ const storeInterDependencies: Partial<Record<StoreName, StoreName[]>> = {
270290
storeStakePoolMetadataJob: ['storeBlock'],
271291
storeStakePoolRewardsJob: ['storeBlock'],
272292
storeStakePools: ['storeBlock'],
293+
storeTransactions: ['storeCredentials', 'storeBlock', 'storeUtxo'],
273294
storeUtxo: ['storeBlock', 'storeAssets']
274295
};
275296

@@ -284,6 +305,7 @@ const projectionStoreDependencies: Record<ProjectionName, StoreName[]> = {
284305
'stake-pool-metadata-job': ['storeStakePoolMetadataJob'],
285306
'stake-pool-metrics-job': ['storePoolMetricsUpdateJob'],
286307
'stake-pool-rewards-job': ['storeStakePoolRewardsJob'],
308+
transaction: ['storeCredentials', 'storeTransactions'],
287309
utxo: ['storeUtxo']
288310
};
289311

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Column, Entity, Index, ManyToMany, PrimaryColumn } from 'typeorm';
2+
import { Hash28ByteBase16 } from '@cardano-sdk/crypto';
3+
import { TransactionEntity } from './Transaction.entity';
4+
5+
export enum CredentialType {
6+
PaymentKey = 'payment_key',
7+
PaymentScript = 'payment_script',
8+
StakeKey = 'stake_key',
9+
StakeScript = 'stake_script'
10+
}
11+
12+
@Entity()
13+
export class CredentialEntity {
14+
@Index()
15+
@PrimaryColumn('varchar')
16+
credentialHash?: Hash28ByteBase16;
17+
18+
@Column('enum', { enum: CredentialType, nullable: false })
19+
credentialType?: CredentialType;
20+
21+
@ManyToMany(() => TransactionEntity, (transaction) => transaction.credentials, { onDelete: 'CASCADE' })
22+
transactions?: TransactionEntity[];
23+
}
24+
25+
export const credentialEntityComparator = (c1: CredentialEntity, c2: CredentialEntity) =>
26+
c1.credentialHash === c2.credentialHash && c1.credentialType === c2.credentialType;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { BlockEntity } from './Block.entity';
2+
import { Cardano, Serialization } from '@cardano-sdk/core';
3+
import { Column, Entity, Index, JoinColumn, JoinTable, ManyToMany, ManyToOne, PrimaryColumn } from 'typeorm';
4+
import { CredentialEntity } from './Credential.entity';
5+
import { OnDeleteCascadeRelationOptions } from './util';
6+
7+
@Entity()
8+
export class TransactionEntity {
9+
@Index()
10+
@PrimaryColumn('varchar')
11+
txId?: Cardano.TransactionId;
12+
13+
@Column('varchar', { nullable: false })
14+
cbor?: Serialization.TxCBOR;
15+
16+
@ManyToOne(() => BlockEntity, OnDeleteCascadeRelationOptions)
17+
@JoinColumn({ name: 'block_id' })
18+
block?: BlockEntity;
19+
20+
@ManyToMany(() => CredentialEntity, (credential) => credential.transactions, { onDelete: 'CASCADE' })
21+
@JoinTable({
22+
inverseJoinColumn: { name: 'credential_id', referencedColumnName: 'credentialHash' },
23+
joinColumn: { name: 'transaction_id', referencedColumnName: 'txId' },
24+
name: 'transaction_credentials'
25+
})
26+
credentials?: CredentialEntity[];
27+
}

packages/projection-typeorm/src/entity/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './Address.entity';
22
export * from './Asset.entity';
33
export * from './Block.entity';
44
export * from './BlockData.entity';
5+
export * from './Credential.entity';
56
export * from './CurrentPoolMetrics.entity';
67
export * from './Handle.entity';
78
export * from './HandleMetadata.entity';
@@ -16,4 +17,5 @@ export * from './PoolRewards.entity';
1617
export * from './StakeKey.entity';
1718
export * from './StakeKeyRegistration.entity';
1819
export * from './StakePool.entity';
20+
export * from './Transaction.entity';
1921
export * from './Tokens.entity';

packages/projection-typeorm/src/operators/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './storeAddresses';
22
export * from './storeAssets';
33
export * from './storeBlock';
4+
export * from './storeCredentials';
45
export * from './storeGovernanceAction';
56
export * from './storeHandles';
67
export * from './storeHandleMetadata';
@@ -11,6 +12,7 @@ export * from './storeStakeKeyRegistrations';
1112
export * from './storeStakePools';
1213
export * from './storeStakePoolMetadataJob';
1314
export * from './storeStakePoolRewardsJob';
15+
export * from './storeTransactions';
1416
export * from './storeUtxo';
1517
export * from './util';
1618
export * from './withTypeormTransaction';

0 commit comments

Comments
 (0)