@meantjs/profile 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/resolved.mjs CHANGED
@@ -41,24 +41,36 @@ export function buildTree(iface, methodName, side, tags) {
41
41
  */
42
42
  export function resolvedForm(iface, profiles, tags, diagnostics) {
43
43
  const methods = {};
44
+ const messages = {};
44
45
  for (const [name, m] of [...iface.methods.entries()].sort(([a], [b]) => (a < b ? -1 : 1))) {
45
46
  const mt = { ...tags.methodTags(name) };
46
47
  if (!mt.effect) {
47
- mt.effect = m.mode === "update" || m.mode === "oneway"
48
+ // A signed message authorizes what someone else submits later (spec section 15.9): as conservative as an update.
49
+ mt.effect = m.mode === "update" || m.mode === "oneway" || m.mode === "message"
48
50
  ? { args: { kind: "write", irreversible: true }, origin: "default" }
49
51
  : { args: { kind: "read", irreversible: false }, origin: "default" };
50
52
  }
53
+ if (m.mode === "message") {
54
+ const { encodeType, typeHash } = iface.messages.get(name); // an EIP-712 message: what a consumer matches a request by
55
+ messages[name] = { encode_type: encodeType, type_hash: typeHash, tags: mt, args: buildTree(iface, name, "args", tags) };
56
+ continue;
57
+ }
51
58
  const f = iface.functions?.get(name); // an EVM function: what a consumer needs to match and decode calldata
52
59
  const abi = f ? { selector: f.selector, signature: f.signature, state_mutability: f.stateMutability } : {};
53
60
  methods[name] = { mode: m.mode, ...abi, tags: mt, args: buildTree(iface, name, "args", tags), results: buildTree(iface, name, "results", tags) };
54
61
  }
62
+ const bound = (doc) => ({
63
+ ...(doc.binds?.deployments ? { deployments: doc.binds.deployments } : {}),
64
+ ...(doc.binds?.eip712?.domain ? { eip712_domain: doc.binds.eip712.domain } : {}),
65
+ });
55
66
  return {
56
67
  format: "candid-profile-resolved",
57
68
  format_version: 0,
58
69
  ...(iface.chain === "evm" ? { chain: "evm" } : {}),
59
70
  interface_id: iface.contract.identities.interface ?? null,
60
- profiles: profiles.map(({ doc, pid }) => ({ name: doc.name, origin: doc.origin, profile_id: pid, ...(doc.binds?.deployments ? { deployments: doc.binds.deployments } : {}) })),
71
+ profiles: profiles.map(({ doc, pid }) => ({ name: doc.name, origin: doc.origin, profile_id: pid, ...bound(doc) })),
61
72
  methods,
73
+ ...(Object.keys(messages).length ? { messages } : {}),
62
74
  diagnostics,
63
75
  };
64
76
  }
package/src/validate.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { profileId } from "./util.mjs";
6
6
  import { compileInterface } from "./compile.mjs";
7
- import { abiInterface, checkDeployments } from "./abi-iface.mjs";
7
+ import { abiInterface, checkDeployments, eip712Of } from "./abi-iface.mjs";
8
8
  import { analyzeProfiles } from "./analyze.mjs";
9
9
  import { resolvedForm } from "./resolved.mjs";
10
10
  import { schemaDiagnostics } from "./schema-core.mjs";
@@ -27,11 +27,15 @@ export async function validateProfile(doc, opts) {
27
27
  }
28
28
  const pid = profileId(doc);
29
29
 
30
- // An EVM contract profile or pack carries its own ABI (spec section 15): it is checked against that.
30
+ // An EVM contract profile or pack carries its own ABI and EIP-712 types (spec sections 15 and 15.9): it is
31
+ // checked against them.
31
32
  if (doc.kind === "contract" || (doc.kind === "pack" && doc.binds.abi !== undefined)) {
32
- const compiled = abiInterface(doc.binds.abi, "binds.abi");
33
+ const eip712 = eip712Of(doc);
34
+ for (const d of eip712.errors) diag("error", "E_EIP712", d.at, d.message);
35
+ if (eip712.errors.length) return { ok: false, profile_id: pid, diagnostics };
36
+ const compiled = abiInterface(doc.binds.abi ?? [], "binds.abi", "contract", doc.binds.eip712 ? { ...eip712, label: "binds.eip712.types" } : null);
33
37
  if (compiled.failure) {
34
- for (const d of compiled.failure) diag("error", "E_ABI", d.at, d.message);
38
+ for (const d of compiled.failure) diag("error", d.at.startsWith("binds.eip712") ? "E_EIP712" : "E_ABI", d.at, d.message);
35
39
  return { ok: false, profile_id: pid, diagnostics };
36
40
  }
37
41
  if (doc.kind === "contract") checkDeployments(doc, diag);