Skip to content

Commit 8686610

Browse files
committed
feat(core): add coreToCsl.txAuxiliaryData
1 parent 48c33e5 commit 8686610

File tree

2 files changed

+118
-12
lines changed

2 files changed

+118
-12
lines changed

packages/core/src/CSL/coreToCsl.ts

+64-12
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@ import * as Cardano from '../Cardano';
33
import {
44
Address,
55
Assets,
6+
AuxiliaryData,
67
BigNum,
78
Certificates,
89
Ed25519Signature,
10+
GeneralTransactionMetadata,
11+
Int,
12+
MetadataList,
13+
MetadataMap,
914
MultiAsset,
1015
PublicKey,
1116
RewardAddress,
@@ -14,6 +19,7 @@ import {
1419
TransactionHash,
1520
TransactionInput,
1621
TransactionInputs,
22+
TransactionMetadatum,
1723
TransactionOutput,
1824
TransactionOutputs,
1925
TransactionUnspentOutput,
@@ -22,13 +28,14 @@ import {
2228
Vkey,
2329
Vkeywitness,
2430
Vkeywitnesses,
25-
Withdrawals
31+
Withdrawals,
32+
hash_auxiliary_data
2633
} from '@emurgo/cardano-serialization-lib-nodejs';
2734

2835
import * as certificate from './certificate';
2936
import { SerializationError } from '../errors';
3037
import { SerializationFailure } from '..';
31-
import { coreToCsl, parseCslAddress } from '.';
38+
import { parseCslAddress } from './parseCslAddress';
3239
export * as certificate from './certificate';
3340

3441
export const tokenMap = (assets: Cardano.TokenMap) => {
@@ -63,14 +70,54 @@ export const txOut = (core: Cardano.TxOut): TransactionOutput =>
6370
export const utxo = (core: Cardano.Utxo[]): TransactionUnspentOutput[] =>
6471
core.map((item) => TransactionUnspentOutput.new(txIn(item[0]), txOut(item[1])));
6572

66-
export const txBody = ({
67-
inputs,
68-
outputs,
69-
fee,
70-
validityInterval,
71-
certificates,
72-
withdrawals
73-
}: Cardano.TxBodyAlonzo): TransactionBody => {
73+
export const txMetadatum = (metadatum: Cardano.Metadatum): TransactionMetadatum => {
74+
switch (typeof metadatum) {
75+
case 'bigint':
76+
return TransactionMetadatum.new_int(Int.new(BigNum.from_str(metadatum.toString())));
77+
case 'string':
78+
return TransactionMetadatum.new_text(metadatum);
79+
default: {
80+
if (Array.isArray(metadatum)) {
81+
const metadataList = MetadataList.new();
82+
for (const metadataItem of metadatum) {
83+
metadataList.add(txMetadatum(metadataItem));
84+
}
85+
return TransactionMetadatum.new_list(metadataList);
86+
} else if (ArrayBuffer.isView(metadatum)) {
87+
return TransactionMetadatum.new_bytes(metadatum);
88+
}
89+
const metadataMap = MetadataMap.new();
90+
for (const [key, data] of metadatum.entries()) {
91+
metadataMap.insert(txMetadatum(key), txMetadatum(data));
92+
}
93+
return TransactionMetadatum.new_map(metadataMap);
94+
}
95+
}
96+
};
97+
98+
export const txMetadata = (blob: Map<bigint, Cardano.Metadatum>): GeneralTransactionMetadata => {
99+
const metadata = GeneralTransactionMetadata.new();
100+
for (const [key, data] of blob.entries()) {
101+
metadata.insert(BigNum.from_str(key.toString()), txMetadatum(data));
102+
}
103+
return metadata;
104+
};
105+
106+
export const txAuxiliaryData = (auxiliaryData?: Cardano.AuxiliaryData): AuxiliaryData | undefined => {
107+
if (!auxiliaryData) return;
108+
const result = AuxiliaryData.new();
109+
// TODO: add support for auxiliaryData.scripts
110+
const { blob } = auxiliaryData.body;
111+
if (blob) {
112+
result.set_metadata(txMetadata(blob));
113+
}
114+
return result;
115+
};
116+
117+
export const txBody = (
118+
{ inputs, outputs, fee, validityInterval, certificates, withdrawals }: Cardano.TxBodyAlonzo,
119+
auxiliaryData?: Cardano.AuxiliaryData
120+
): TransactionBody => {
74121
const cslInputs = TransactionInputs.new();
75122
for (const input of inputs) {
76123
cslInputs.add(txIn(input));
@@ -109,10 +156,14 @@ export const txBody = ({
109156
}
110157
cslBody.set_withdrawals(cslWithdrawals);
111158
}
159+
const cslAuxiliaryData = txAuxiliaryData(auxiliaryData);
160+
if (cslAuxiliaryData) {
161+
cslBody.set_auxiliary_data_hash(hash_auxiliary_data(cslAuxiliaryData));
162+
}
112163
return cslBody;
113164
};
114165

115-
export const tx = ({ body, witness }: Cardano.NewTxAlonzo): Transaction => {
166+
export const tx = ({ body, witness, auxiliaryData }: Cardano.NewTxAlonzo): Transaction => {
116167
const witnessSet = TransactionWitnessSet.new();
117168
const vkeyWitnesses = Vkeywitnesses.new();
118169
for (const [vkey, signature] of witness.signatures.entries()) {
@@ -121,5 +172,6 @@ export const tx = ({ body, witness }: Cardano.NewTxAlonzo): Transaction => {
121172
vkeyWitnesses.add(vkeyWitness);
122173
}
123174
witnessSet.set_vkeys(vkeyWitnesses);
124-
return Transaction.new(coreToCsl.txBody(body), witnessSet);
175+
// Possible optimization: only convert auxiliary data once
176+
return Transaction.new(txBody(body, auxiliaryData), witnessSet, txAuxiliaryData(auxiliaryData));
125177
};

packages/core/test/CSL/coreToCsl.test.ts

+54
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable max-len */
22
import { Asset, CSL, Cardano, coreToCsl } from '../../src';
3+
import { BigNum } from '@emurgo/cardano-serialization-lib-nodejs';
34

45
const txIn: Cardano.TxIn = {
56
address: Cardano.Address(
@@ -122,4 +123,57 @@ describe('coreToCsl', () => {
122123
expect(Buffer.from(witness.vkey().public_key().as_bytes()).toString('hex')).toBe(vkey);
123124
expect(witness.signature().to_hex()).toBe(signature);
124125
});
126+
describe('txAuxiliaryData', () => {
127+
it('returns undefined for undefined data', () => expect(coreToCsl.txAuxiliaryData()).toBeUndefined());
128+
129+
describe('txMetadata', () => {
130+
// eslint-disable-next-line unicorn/consistent-function-scoping
131+
const convertMetadatum = (metadatum: Cardano.Metadatum) => {
132+
const label = 123n;
133+
const auxiliaryData = coreToCsl.txAuxiliaryData({ body: { blob: new Map([[label, metadatum]]) } });
134+
return auxiliaryData?.metadata()?.get(BigNum.from_str(label.toString()));
135+
};
136+
137+
it('converts number', () => {
138+
const number = 1234n;
139+
const metadatum = convertMetadatum(number);
140+
expect(metadatum?.as_int().as_positive()?.to_str()).toBe(number.toString());
141+
});
142+
143+
it('converts text', () => {
144+
const str = 'str';
145+
const metadatum = convertMetadatum(str);
146+
expect(metadatum?.as_text()).toBe(str);
147+
});
148+
149+
it('converts list', () => {
150+
const list = ['str1', 'str2'];
151+
const metadatum = convertMetadatum(list);
152+
const cslList = metadatum?.as_list();
153+
expect(cslList?.len()).toBe(list.length);
154+
expect(cslList?.get(0).as_text()).toBe(list[0]);
155+
expect(cslList?.get(1).as_text()).toBe(list[1]);
156+
});
157+
158+
test('converts bytes', () => {
159+
const bytes = Buffer.from('str');
160+
const metadatum = convertMetadatum(bytes);
161+
expect(metadatum?.as_bytes().buffer).toEqual(bytes.buffer);
162+
});
163+
164+
it('converts map', () => {
165+
const map = new Map<Cardano.Metadatum, Cardano.Metadatum>([
166+
[123n, 1234n],
167+
['key', 'value']
168+
]);
169+
const metadatum = convertMetadatum(map);
170+
const cslMap = metadatum?.as_map();
171+
expect(cslMap?.len()).toBe(map.size);
172+
expect(cslMap?.get(convertMetadatum(123n)!).as_int().as_positive()?.to_str()).toBe('1234');
173+
expect(cslMap?.get(convertMetadatum('key')!).as_text()).toBe('value');
174+
});
175+
});
176+
177+
it.todo('txScripts');
178+
});
125179
});

0 commit comments

Comments
 (0)