From a3cd1bf98eb1dab18c7424106f50ced065946e1f Mon Sep 17 00:00:00 2001 From: GuilaneDen <83951892+GuilaneDen@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:01:50 +0100 Subject: [PATCH] feat: implemented publicInfoForIp --- src/Concordium.ts | 40 +++++++++++++++++++++++++++++++++++++++- src/serialization.ts | 18 ++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/Concordium.ts b/src/Concordium.ts index aaca075..77ee2d8 100644 --- a/src/Concordium.ts +++ b/src/Concordium.ts @@ -15,7 +15,8 @@ import { serializeUpdateContract, serializeTransactionPayloads, serializeUpdateCredentials, - serializeCredentialDeployment + serializeCredentialDeployment, + serializePublicInfoForIp } from "./serialization"; import { encodeInt32, encodeInt8, encodeWord64 } from "./utils"; @@ -102,6 +103,7 @@ const INS = { SIGN_TRANSFER_TO_PUBLIC: 0x12, SIGN_CONFIGURE_DELEGATION: 0x17, SIGN_CONFIGURE_BAKER: 0x18, + SIGN_PUBLIC_INFO_FOR_IP: 0x20, GET_APP_NAME: 0x21, SIGN_UPDATE_CREDENTIALS: 0x31, SIGN_TRANSFER_MEMO: 0x32, @@ -625,6 +627,42 @@ export default class Concordium { }; } + async signPublicInfoForIp(txn, path: string): Promise<{ signature: string[] }> { + + const { payloadIdCredPubAndRegIdAndKeysLenght, payloadKeys, payloadThreshold } = serializePublicInfoForIp(txn, path); + + let response; + + response = await this.sendToDevice( + INS.SIGN_PUBLIC_INFO_FOR_IP, + P1_INITIAL_PACKET, + NONE, + payloadIdCredPubAndRegIdAndKeysLenght + ); + + for (let i = 0; i < payloadKeys.length; i++) { + response = await this.sendToDevice( + INS.SIGN_PUBLIC_INFO_FOR_IP, + P1_VERIFICATION_KEY, + NONE, + payloadKeys[i] + ); + } + + response = await this.sendToDevice( + INS.SIGN_PUBLIC_INFO_FOR_IP, + P1_SIGNATURE_THRESHOLD, + NONE, + payloadThreshold + ); + + if (response.length === 1) throw new Error("User has declined."); + + return { + signature: response.toString("hex"), + }; + } + async signCredentialDeployment(txn, isNew: boolean, addressOrExpiry: string | BigInt, path: string): Promise<{ signature: string[] }> { const { payloadDerivationPath, numberOfVerificationKeys, keyIndexAndSchemeAndVerificationKey, thresholdAndRegIdAndIPIdentity, encIdCredPubShareAndKey, validToAndCreatedAtAndAttributesLength, tag, valueLength, value, proofLength, proofs } = serializeCredentialDeployment(txn, path); diff --git a/src/serialization.ts b/src/serialization.ts index 1f087f1..bf06674 100644 --- a/src/serialization.ts +++ b/src/serialization.ts @@ -4,6 +4,7 @@ import { DataBlob } from "@concordium/common-sdk/lib/types/DataBlob"; import { Buffer as NodeBuffer } from 'buffer/index'; import { AccountAddress } from "@concordium/web-sdk"; import { serializeCredentialDeploymentInfo } from "@concordium/common-sdk/lib/serialization"; +import { encodeWord8, encodeWord8FromString, serializeMap, serializeVerifyKey } from "@concordium/common-sdk/lib/serializationHelpers"; const MAX_CHUNK_SIZE = 255; const MAX_SCHEDULE_CHUNK_SIZE = 15; @@ -455,3 +456,20 @@ export const serializeUpdateCredentials = (txn: any, path: string): { payloadHea offset += ONE_OCTET_LENGTH; return { payloadHeaderKindAndIndexLength, credentialIndex, numberOfVerificationKeys, keyIndexAndSchemeAndVerificationKey, thresholdAndRegIdAndIPIdentity, encIdCredPubShareAndKey, validToAndCreatedAtAndAttributesLength, attributesLength, tag, valueLength, value, proofLength, proofs, credentialIdCount, credentialIds, threshold }; }; + +export const serializePublicInfoForIp = (txn: any, path: string): { payloadIdCredPubAndRegIdAndKeysLenght: Buffer, payloadKeys: Buffer[], payloadThreshold: Buffer } => { + + const serializedIdCredPub = Buffer.from(txn.idCredPub, 'hex'); + const serializedRegId = Buffer.from(txn.regId, 'hex'); + const serializedPublicKeys = serializeMap(txn.publicKeys.keys, encodeWord8, encodeWord8FromString, serializeVerifyKey); + const payloadThreshold = encodeInt8(txn.publicKeys.threshold); + + const payloadIdCredPubAndRegIdAndKeysLenght = Buffer.concat([serializedIdCredPub, serializedRegId, serializedPublicKeys.subarray(0, 1)]); + + let payloadKeys: Buffer[] = []; + for (let i = 0; i < Object.keys(txn.publicKeys.keys).length; i++) { + payloadKeys.push(Buffer.concat([serializedPublicKeys.subarray(i * (KEY_LENGTH + 2*ONE_OCTET_LENGTH) + 1, (i + 1) * (KEY_LENGTH + 2*ONE_OCTET_LENGTH) + 1)])); + } + + return { payloadIdCredPubAndRegIdAndKeysLenght, payloadKeys, payloadThreshold }; +};