From 6952bd40bf534f79d5bd73a85f959c1389858435 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 1 Oct 2024 13:02:26 +0000 Subject: [PATCH 1/3] feat: note fields in TS artifact --- yarn-project/foundation/src/abi/abi.ts | 14 ++++++++++ .../types/src/abi/contract_artifact.ts | 26 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index a25a802dace..160be402bff 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -309,6 +309,20 @@ export type ContractNote = { * Type of the note (e.g., 'TransparentNote') */ typ: string; + /** + * Fields of the note. + */ + fields: NoteField[]; +}; + +/** Type representing a field of a note (e.g. `amount` in `TokenNote`). */ +export type NoteField = { + /** Name of the field (e.g. `amount`). */ + name: string; + /** Index where the note field starts in the serialized note array. */ + index: number; + /** Whether the field can be unset when creating the note (in the partial notes flow). */ + nullable: boolean; }; /** diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index b7484f0c0b9..84eb0f14099 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -256,7 +256,23 @@ function getStorageLayout(input: NoirCompiledContract) { function getNoteTypes(input: NoirCompiledContract) { type t = { kind: string; - fields: [{ kind: string; sign: boolean; value: string }, { kind: string; value: string }]; + fields: [ + { kind: string; sign: boolean; value: string }, + { kind: string; value: string }, + { + fields: { + name: string; + value: { + kind: string; + value: string | boolean; + fields: [ + { name: string; value: { kind: string; sign: boolean; value: string } }, + { name: string; value: { kind: string; value: boolean } }, + ]; + }; + }[]; + }, + ]; }; const notes = input.outputs.globals.notes as t[]; @@ -269,9 +285,17 @@ function getNoteTypes(input: NoirCompiledContract) { const name = note.fields[1].value as string; // Note id is encoded as a hex string const id = NoteSelector.fromField(Fr.fromString(note.fields[0].value)); + const fields = note.fields[2].fields.map(field => { + return { + name: field.name, + index: Number(field.value.fields[0].value.value), // TODO: is this hex or decimal? + nullable: field.value.fields[1].value.value, + }; + }); acc[name] = { id, typ: name, + fields, }; return acc; }, {}); From d162d19dd6d9010e8d810bf1e8da833d3b380da0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 1 Oct 2024 13:38:09 +0000 Subject: [PATCH 2/3] fix --- yarn-project/types/src/abi/contract_artifact.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 84eb0f14099..506beddd8a8 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -288,7 +288,7 @@ function getNoteTypes(input: NoirCompiledContract) { const fields = note.fields[2].fields.map(field => { return { name: field.name, - index: Number(field.value.fields[0].value.value), // TODO: is this hex or decimal? + index: parseInt(field.value.fields[0].value.value, 16), nullable: field.value.fields[1].value.value, }; }); From a2a3ce2ad2437a65ea46ca2bfacb74c938845a30 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 2 Oct 2024 07:25:49 +0000 Subject: [PATCH 3/3] cleanup --- .../types/src/abi/contract_artifact.ts | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 506beddd8a8..a474920eddf 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -254,38 +254,31 @@ function getStorageLayout(input: NoirCompiledContract) { * @return A record of the note types and their ids */ function getNoteTypes(input: NoirCompiledContract) { - type t = { - kind: string; - fields: [ - { kind: string; sign: boolean; value: string }, - { kind: string; value: string }, - { - fields: { - name: string; - value: { - kind: string; - value: string | boolean; - fields: [ - { name: string; value: { kind: string; sign: boolean; value: string } }, - { name: string; value: { kind: string; value: boolean } }, - ]; - }; - }[]; - }, - ]; - }; - - const notes = input.outputs.globals.notes as t[]; + // The type is useless here as it does not give us any guarantee (e.g. `AbiValue` can be one of many different + // types) so we nuke it and later we manually check the values are as we expect. + const notes = input.outputs.globals.notes as any[]; if (!notes) { return {}; } return notes.reduce((acc: Record, note) => { - const name = note.fields[1].value as string; - // Note id is encoded as a hex string - const id = NoteSelector.fromField(Fr.fromString(note.fields[0].value)); - const fields = note.fields[2].fields.map(field => { + const noteFields = note.fields; + + // We find note type id by looking for respective kinds as each of them is unique + const rawNoteTypeId = noteFields.find((field: any) => field.kind === 'integer'); + const rawName = noteFields.find((field: any) => field.kind === 'string'); + const rawNoteFields = noteFields.find((field: any) => field.kind === 'struct'); + + if (!rawNoteTypeId || !rawName || !rawNoteFields) { + throw new Error(`Could not find note type id, name or fields for note ${note}`); + } + + const noteTypeId = NoteSelector.fromField(Fr.fromString(rawNoteTypeId.value)); + const name = rawName.value as string; + + // Note type id is encoded as a hex string + const fields = rawNoteFields.fields.map((field: any) => { return { name: field.name, index: parseInt(field.value.fields[0].value.value, 16), @@ -293,7 +286,7 @@ function getNoteTypes(input: NoirCompiledContract) { }; }); acc[name] = { - id, + id: noteTypeId, typ: name, fields, };