Skip to content

Commit 35220b6

Browse files
authored
Merge pull request #123 from unicitynetwork/issue-122
#122 Add network id to unicity id mint transaction
2 parents 68bc1e5 + 5476722 commit 35220b6

14 files changed

Lines changed: 73 additions & 29 deletions

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default defineConfig(
1919
...globals.node
2020
},
2121
parserOptions: {
22-
project: ['./tsconfig.eslint.json']
22+
project: ['./tsconfig.json']
2323
},
2424
sourceType: 'module'
2525
},

package-lock.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"./lib/*": "./lib/*.js"
99
},
1010
"scripts": {
11-
"build": "tsc",
12-
"build:check": "tsc --project tsconfig.eslint.json --noEmit",
11+
"build": "tsc --project tsconfig.build.json",
12+
"build:check": "tsc --noEmit",
1313
"lint": "eslint \"src/**/*\" \"tests/**/*\"",
1414
"lint:fix": "eslint \"src/**/*\" \"tests/**/*\" --fix",
1515
"test": "npm run-script test:unit",

src/predicate/builtin/UnicityIdPredicateUnlockScript.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { SigningService } from '../../crypto/secp256k1/SigningService.js';
44
import { CborDeserializer } from '../../serialization/cbor/CborDeserializer.js';
55
import { CborSerializer } from '../../serialization/cbor/CborSerializer.js';
66
import { ITransaction } from '../../transaction/ITransaction.js';
7+
import { TokenId } from '../../transaction/TokenId.js';
78
import { UnicityIdToken } from '../../unicity-id/UnicityIdToken.js';
89
import { IUnlockScript } from '../IUnlockScript.js';
910

@@ -42,7 +43,8 @@ export class UnicityIdPredicateUnlockScript implements IUnlockScript {
4243
signingService: SigningService,
4344
): Promise<UnicityIdPredicateUnlockScript> {
4445
const predicate = UnicityIdPredicate.fromPredicate(transaction.lockScript);
45-
if (!token.id.equals(await predicate.unicityId.toTokenId())) {
46+
const tokenId = await TokenId.fromSalt(token.genesis.networkId, await predicate.unicityId.toTokenSalt());
47+
if (!token.id.equals(tokenId)) {
4648
throw new Error('Invalid Unicity ID for transaction');
4749
}
4850

src/predicate/builtin/verification/UnicityIdPredicateVerifier.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { IBuiltInPredicateVerifier } from './IBuiltInPredicateVerifier.js';
22
import { RootTrustBase } from '../../../api/bft/RootTrustBase.js';
33
import { DataHash } from '../../../crypto/hash/DataHash.js';
4+
import { TokenId } from '../../../transaction/TokenId.js';
45
import { VerificationResult } from '../../../verification/VerificationResult.js';
56
import { VerificationStatus } from '../../../verification/VerificationStatus.js';
67
import { EncodedPredicate } from '../../EncodedPredicate.js';
@@ -40,7 +41,7 @@ export class UnicityIdPredicateVerifier implements IBuiltInPredicateVerifier {
4041
const predicate = UnicityIdPredicate.fromPredicate(encodedPredicate);
4142
const decodedUnlockScript = await UnicityIdPredicateUnlockScript.decode(unlockScript);
4243

43-
const tokenId = await predicate.unicityId.toTokenId();
44+
const tokenId = await TokenId.fromSalt(this.trustBase.networkId, await predicate.unicityId.toTokenSalt());
4445
if (!tokenId.equals(decodedUnlockScript.token.id)) {
4546
return new VerificationResult('UnicityIdPredicateVerifier', VerificationStatus.FAIL, 'Token ID mismatch.');
4647
}

src/transaction/CertifiedMintTransaction.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
* Mint transaction bundled with a verified inclusion proof.
2323
*/
2424
export class CertifiedMintTransaction implements ITransaction {
25+
private readonly _brand = 'CertifiedMintTransaction' as const;
26+
2527
private constructor(
2628
private readonly transaction: MintTransaction,
2729
public readonly inclusionProof: InclusionProof,

src/transaction/MintTransaction.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export class MintTransaction implements ITransaction {
2828
public static readonly CBOR_TAG = 39041n;
2929
private static readonly VERSION = 1n;
3030

31+
private readonly _brand = 'MintTransaction' as const;
32+
3133
private constructor(
3234
public readonly sourceStateHash: MintTransactionState,
3335
public readonly lockScript: EncodedPredicate,

src/transaction/verification/rule/CertifiedUnicityIdMintTransactionVerificationRule.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ export class CertifiedUnicityIdMintTransactionVerificationRule {
3434
): Promise<VerificationResult<VerificationStatus>> {
3535
const results: VerificationResult<unknown>[] = [];
3636

37+
if (!genesis.networkId.equals(trustBase.networkId)) {
38+
results.push(new VerificationResult('MintNetworkMatchesTrustBaseRule', VerificationStatus.FAIL));
39+
return new VerificationResult(
40+
'CertifiedUnicityIdMintTransactionVerificationRule',
41+
VerificationStatus.FAIL,
42+
'Mint network does not match trust base.',
43+
results,
44+
);
45+
}
46+
results.push(new VerificationResult('MintNetworkMatchesTrustBaseRule', VerificationStatus.OK));
47+
3748
if (issuerPublicKey !== null) {
3849
const expectedLockScript = EncodedPredicate.fromPredicate(SignaturePredicate.create(issuerPublicKey));
3950
if (!EncodedPredicate.equals(expectedLockScript, genesis.lockScript)) {

src/unicity-id/CertifiedUnicityIdMintTransaction.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { UnicityId } from './UnicityId.js';
22
import { UnicityIdMintTransaction } from './UnicityIdMintTransaction.js';
33
import { RootTrustBase } from '../api/bft/RootTrustBase.js';
44
import { InclusionProof } from '../api/InclusionProof.js';
5+
import { NetworkId } from '../api/NetworkId.js';
56
import { DataHash } from '../crypto/hash/DataHash.js';
67
import { SignaturePredicate } from '../predicate/builtin/SignaturePredicate.js';
78
import { EncodedPredicate } from '../predicate/EncodedPredicate.js';
@@ -21,6 +22,8 @@ import { dedent } from '../util/StringUtils.js';
2122
* Unicity-id mint transaction bundled with a verified inclusion proof.
2223
*/
2324
export class CertifiedUnicityIdMintTransaction implements ITransaction {
25+
private readonly _brand = 'CertifiedUnicityIdMintTransaction' as const;
26+
2427
public constructor(
2528
private readonly transaction: UnicityIdMintTransaction,
2629
public readonly inclusionProof: InclusionProof,
@@ -40,6 +43,13 @@ export class CertifiedUnicityIdMintTransaction implements ITransaction {
4043
return this.transaction.lockScript;
4144
}
4245

46+
/**
47+
* @returns {NetworkId} Network identifier of the inner transaction.
48+
*/
49+
public get networkId(): NetworkId {
50+
return this.transaction.networkId;
51+
}
52+
4353
/**
4454
* @returns {EncodedPredicate} Recipient predicate of the inner transaction.
4555
*/

src/unicity-id/UnicityId.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { DataHasher } from '../crypto/hash/DataHasher.js';
22
import { HashAlgorithm } from '../crypto/hash/HashAlgorithm.js';
33
import { CborDeserializer } from '../serialization/cbor/CborDeserializer.js';
44
import { CborSerializer } from '../serialization/cbor/CborSerializer.js';
5-
import { TokenId } from '../transaction/TokenId.js';
5+
import { TokenSalt } from '../transaction/TokenSalt.js';
66

77
/**
88
* Human-readable identifier (`@domain/name`) people use to send tokens.
9-
* The bound {@link TokenId} can be derived from it via {@link toTokenId}.
9+
* The bound {@link TokenSalt} can be derived from it via {@link toTokenSalt}.
1010
*/
1111
export class UnicityId {
1212
public constructor(
@@ -48,11 +48,11 @@ export class UnicityId {
4848
}
4949

5050
/**
51-
* Derive the {@link TokenId} bound to this unicity id.
51+
* Derive the {@link TokenSalt} bound to this unicity id.
5252
*
53-
* @returns {Promise<TokenId>} Derived token id.
53+
* @returns {Promise<TokenSalt>} Derived token id.
5454
*/
55-
public async toTokenId(): Promise<TokenId> {
55+
public async toTokenSalt(): Promise<TokenSalt> {
5656
const hash = await new DataHasher(HashAlgorithm.SHA256)
5757
.update(
5858
CborSerializer.encodeArray(
@@ -63,6 +63,6 @@ export class UnicityId {
6363
)
6464
.digest();
6565

66-
return new TokenId(hash.data);
66+
return TokenSalt.fromBytes(hash.data);
6767
}
6868
}

0 commit comments

Comments
 (0)