@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/CHANGELOG.md +24 -0
- package/README.md +12 -4
- package/data/packs/dai-permit.profile.json +117 -0
- package/data/packs/erc20.profile.json +10 -2
- package/data/packs/erc2612.profile.json +204 -0
- package/data/packs/icrc1.profile.json +5 -1
- package/data/packs/icrc2.profile.json +8 -1
- package/data/packs/permit2.profile.json +451 -0
- package/data/profile-v0.schema.json +204 -9
- package/data/profile-v0.validate.mjs +11 -2
- package/package.json +1 -1
- package/src/abi-iface.mjs +49 -7
- package/src/abi-pack.mjs +5 -2
- package/src/abi.mjs +111 -4
- package/src/analyze.mjs +40 -6
- package/src/browser.mjs +6 -1
- package/src/checks.mjs +70 -1
- package/src/evm.d.mts +18 -3
- package/src/evm.mjs +5 -1
- package/src/resolve.mjs +45 -7
- package/src/resolved.mjs +14 -2
- package/src/validate.mjs +8 -4
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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);
|