diff --git a/packages/wallet-connectors/src/WalletConnect.ts b/packages/wallet-connectors/src/WalletConnect.ts index d4b7237..ed1d28a 100644 --- a/packages/wallet-connectors/src/WalletConnect.ts +++ b/packages/wallet-connectors/src/WalletConnect.ts @@ -122,7 +122,8 @@ function serializeUpdateContractMessage( } /** - * Convert schema into the object format expected by the Mobile crypto library. + * Convert schema into the object format expected by the Mobile crypto library (function 'parameter_to_json') + * which decodes the parameter before presenting it to the user for approval. * @param schema The schema object. */ function convertSchemaFormat(schema: Schema | undefined) { diff --git a/samples/contractupdate/src/useContractSchemaRpc.ts b/samples/contractupdate/src/useContractSchemaRpc.ts index b398f2f..32ed83d 100644 --- a/samples/contractupdate/src/useContractSchemaRpc.ts +++ b/samples/contractupdate/src/useContractSchemaRpc.ts @@ -10,21 +10,31 @@ export interface SchemaRpcResult { schema: Schema; } -function findCustomSections(m: WebAssembly.Module) { +function findCustomSections(m: WebAssembly.Module, moduleVersion: number) { function getCustomSections(sectionName: string, schemaVersion: SchemaVersion | undefined) { const s = WebAssembly.Module.customSections(m, sectionName); return s.length === 0 ? undefined : { sectionName, schemaVersion, contents: s }; } - // First look for embedded version, then v1, then v0. The "v"s being off by 1 is not an error. - return ( - getCustomSections('concordium-schema', undefined) || - getCustomSections('concordium-schema-v2', SchemaVersion.V1) || - getCustomSections('concordium-schema-v1', SchemaVersion.V0) - ); + + // First look for section containing schema with embedded version, then "-v1" or "-v2" depending on the module version. + // See also comment in 'useContractSchemaRpc'. + switch (moduleVersion) { + case 0: + return ( + getCustomSections('concordium-schema', undefined) || // always v0 + getCustomSections('concordium-schema-v1', SchemaVersion.V0) // v0 (not a typo) + ); + case 1: + return ( + getCustomSections('concordium-schema', undefined) || // v1, v2, or v3 + getCustomSections('concordium-schema-v2', SchemaVersion.V1) // v1 (not a typo) + ); + } + return getCustomSections('concordium-schema', undefined); // expecting to find this section in future module versions } -function findSchema(m: WebAssembly.Module): Result { - const sections = findCustomSections(m); +function findSchema(m: WebAssembly.Module, moduleVersion: 0 | 1): Result { + const sections = findCustomSections(m, moduleVersion); if (!sections) { return ok(undefined); } @@ -39,13 +49,25 @@ export function useContractSchemaRpc(rpc: ConcordiumGRPCClient, contract: Info) const [result, setResult] = useState>(); useEffect(() => { ResultAsync.fromPromise(rpc.getModuleSource(new ModuleReference(contract.moduleRef)), errorString) - .andThen((r) => { - if (!r) { + .andThen(({ version, source }) => { + if (source.length === 0) { return err('module source is empty'); } - return ResultAsync.fromPromise(WebAssembly.compile(r.source), errorString); + // The module can contain a schema in one of two different custom sections. + // The supported sections depend on the module version. + // The schema version can be either defined by the section name or embedded into the actual schema: + // - Both v0 and v1 modules support the section 'concordium-schema' where the schema includes the version. + // - For v0 modules this is always a v0 schema. + // - For v1 modules this can be a v1, v2, or v3 schema. + // - V0 modules additionally support section 'concordium-schema-v1' which always contain a v0 schema (not a typo). + // - V1 modules additionally support section 'concordium-schema-v2' which always contain a v1 schema (not a typo). + // The section 'concordium-schema' is the most common and is what the current tooling produces. + return ResultAsync.fromPromise( + WebAssembly.compile(source).then((module) => ({ module, version })), + errorString + ); }) - .andThen(findSchema) + .andThen(({ module, version }) => findSchema(module, version)) .then(setResult); }, [contract, rpc]); return result;