@meantjs/profile 0.4.0 → 0.6.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 CHANGED
@@ -2,6 +2,37 @@
2
2
 
3
3
  The five Candid Profile library packages (`@meantjs/profile`, `/format`, `/consent`, `/tools`, `/reconcile`) release together under one version and pin each other exactly; a version appears here even when this package did not change. Release steps: `docs/releasing.md` in the repository.
4
4
 
5
+ ## 0.6.0 — 2026-11-01
6
+
7
+ - x402's usage-based payment, x402's other networks and USDC's permit (D-059, experimental). New standard contract
8
+ profiles, shipped beside the packs: `x402-upto-permit2`, x402's `upto` payment through Permit2 (witness
9
+ `Witness(address to,address facilitator,uint256 validAfter)`), its spender pinned to x402's `upto` proxy and its
10
+ grant the maximum to `witness.to`; and `usdc-domain-usdc`, USDC's messages on the eleven chains where it signs under
11
+ the domain name `USDC` (Base Sepolia among them). `usdc` and `usdc-domain-usdc` also read USDC's EIP-2612 `Permit`
12
+ (`approve`, a grant to `spender` that never ends). `usdc` lists chains 1, 137, 8453, 42161, 43113, 43114 and 421614;
13
+ `x402-exact-permit2` 20 networks; `permit2` 23. Their profile ids changed. `usdc-base-sepolia` is unchanged and kept
14
+ for 0.5.0 code; `usdc-domain-usdc` reads the same messages there with the same words.
15
+
16
+ ## 0.5.0 — 2026-10-30
17
+
18
+ - Pins, experimental (spec §15.4, D-058): the new tag `fixed`, with `value` one address, says that a profile describes
19
+ a call or an EIP-712 message only with that address at an `address` position of its arguments. Elsewhere it is
20
+ `E_TAG_TARGET` or `E_TAG_NOT_APPLICABLE`, a value with a bad checksum `E_ADDRESS_CHECKSUM`, and two profiles that pin
21
+ one position to different addresses conflict in any layers (`E_CONFLICT`, at the lower one). A profile with a pin
22
+ that does not hold supplies only its effects, without grants, and its pins that hold; a pin's error is never an
23
+ `I_PACK_ANNOTATION_SKIPPED`. The resolved form carries the tag.
24
+ - New standard contract profiles, shipped beside the packs: `usdc` and `usdc-base-sepolia` (USDC's EIP-3009
25
+ messages `TransferWithAuthorization`, `ReceiveWithAuthorization` and `CancelAuthorization` on Ethereum, Base and
26
+ Arbitrum, and on Base Sepolia, whose USDC signs under another domain name), and `x402-exact-permit2` (x402's
27
+ `exact` payment through Permit2, its spender pinned to x402's proxy). The `permit2` profile also lists Base and Base
28
+ Sepolia (chains 8453 and 84532), so its profile id changed.
29
+ - A contract profile resolved against another ABI (`resolveService({ abi })`, `candid-profile resolve --abi`) reports
30
+ `W_REBOUND` and `E_STALE` at `binds.abi`, naming the identity of its ABI (spec §15.3, D-057). They were reported at
31
+ `binds.interface_id`, which a contract profile does not have, and `W_REBOUND` read "profile is bound to undefined".
32
+ Canister profiles are unchanged.
33
+ - Docs: the spec now lists `named` among the tags a stale profile does not supply, as the resolver has done since D-045;
34
+ the README and `served.mjs` no longer point at the kit, which is not public yet.
35
+
5
36
  ## 0.4.0 — 2026-10-30
6
37
 
7
38
  - What a call grants (spec §5.3, D-056): an `effect` of kind `transfer` or `approve` may carry `grant`, the positions of
package/README.md CHANGED
@@ -146,7 +146,7 @@ const r = await resolveService({ did, validateSchema, profiles: doc ? [{ doc }]
146
146
 
147
147
  A canister serves its profile as the public custom section `icp:public candid:profile`. Reading the bytes is the
148
148
  consumer's job (one certified `read_state` of `/canister/<id>/metadata/candid:service` and `.../candid:profile`;
149
- `packages/kit` `fetch` does it with `@icp-sdk/core`); this package checks what came back:
149
+ the project's kit, not public yet, does it with `@icp-sdk/core`); this package checks what came back:
150
150
 
151
151
  ```js
152
152
  import { readServedProfile, resolveService } from "@meantjs/profile";
@@ -162,7 +162,7 @@ const r = await resolveService({ did: serviceText, profiles: served.ok ? [{ doc:
162
162
  installed yet (a module does not know the id it will run as); any other non-string throws.
163
163
  - Binding is the resolver's usual rule (spec section 7): resolve against the `candid:service` the same canister
164
164
  serves, so a profile for another interface is `rebound` or `stale` as any other.
165
- - Tests: `test/served.test.mjs`; end to end on PocketIC in `packages/kit/pocketic/`.
165
+ - Tests: `test/served.test.mjs`; end to end on PocketIC in the kit's tests, which are not public yet.
166
166
 
167
167
  ## EVM contracts (experimental, spec section 15, D-054 and D-055)
168
168
 
@@ -186,8 +186,15 @@ r.resolved.methods.transfer.tags.intent.args.template; // "Send {wad} to {dst}":
186
186
  (`PermitSingle(0).details.amount`) and listed under the resolved form's `messages` with its `encode_type` and
187
187
  `type_hash`. `amount.token` names an amount's token by an `address` field (`E_TOKEN_PATH` otherwise). Bad types, a
188
188
  message named like a function and two meanings for one type name are `E_EIP712`. Standard files: the `erc2612`
189
- pack, and the `permit2` and `dai-permit` contract profiles shipped beside the packs
190
- (`@meantjs/profile/packs/permit2.profile.json`); `loadPacks()` returns the packs only.
189
+ pack, and the contract profiles `permit2`, `dai-permit`, `usdc` and `usdc-domain-usdc` (USDC's EIP-3009 messages
190
+ and permit, under its two domain names), `usdc-base-sepolia` (as 0.5.0 published it), `x402-exact-permit2` and
191
+ `x402-upto-permit2`, shipped beside the packs (`@meantjs/profile/packs/permit2.profile.json`); `loadPacks()`
192
+ returns the packs only.
193
+ - **Pins** (`fixed`, spec §15.4, D-058): an `address` in the arguments of a function or a message that the profile
194
+ describes only with one value, as each of x402's Permit2 payments holds its scheme's proxy as its spender. A pin
195
+ that does not hold (another place or type, a bad checksum, an address that does not resolve, another value pinned
196
+ by any profile) is an error, and its profile then supplies only its effects, without grants, and its pins that
197
+ hold.
191
198
  - **Refused for now:** overloaded function names and unreadable fragments (`E_ABI`); `idempotency`, `outcome`, `list`,
192
199
  `names` and `named` on a contract (`E_TAG_TARGET`); `account` and `subaccount` (`E_TAG_NOT_APPLICABLE`); `[ ]`
193
200
  template segments (`E_TEMPLATE`).
@@ -5,7 +5,7 @@
5
5
  "name": "permit2",
6
6
  "origin": "third_party",
7
7
  "language": "en",
8
- "description": "Uniswap's Permit2 (spec section 15.9, experimental): its AllowanceTransfer messages (PermitSingle, PermitBatch), which set allowances, and its SignatureTransfer messages (PermitTransferFrom, PermitBatchTransferFrom), which authorize one transfer. Witness messages (PermitWitnessTransferFrom) are left out: each protocol adds its own witness type (O1). Bound to the deployments ERC-7730's own Permit2 example lists, so a look-alike contract named \"Permit2\" gets none of these words. Amounts are in the token the message names: a consumer supplies that token's decimals() and symbol(), and shows its address beside the symbol.",
8
+ "description": "Uniswap's Permit2 (spec section 15.9, experimental): its AllowanceTransfer messages (PermitSingle, PermitBatch), which set allowances, and its SignatureTransfer messages (PermitTransferFrom, PermitBatchTransferFrom), which authorize one transfer. Witness messages (PermitWitnessTransferFrom) are left out: each protocol adds its own witness type, in a profile of its own (O9; x402's are x402-exact-permit2 and x402-upto-permit2). Bound to the deployments ERC-7730's own Permit2 example lists (chains 1 and 42161) and to the other networks x402 names, whose Permit2 code and domain were read on chain (Base and Base Sepolia on 2026-10-30, the others on 2026-11-01), so a look-alike contract named \"Permit2\" gets none of these words. Amounts are in the token the message names: a consumer supplies that token's decimals() and symbol(), and shows its address beside the symbol.",
9
9
  "binds": {
10
10
  "eip712": {
11
11
  "domain": {
@@ -111,9 +111,93 @@
111
111
  "chain_id": 1,
112
112
  "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
113
113
  },
114
+ {
115
+ "chain_id": 14,
116
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
117
+ },
118
+ {
119
+ "chain_id": 50,
120
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
121
+ },
122
+ {
123
+ "chain_id": 51,
124
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
125
+ },
126
+ {
127
+ "chain_id": 137,
128
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
129
+ },
130
+ {
131
+ "chain_id": 143,
132
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
133
+ },
134
+ {
135
+ "chain_id": 988,
136
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
137
+ },
138
+ {
139
+ "chain_id": 1328,
140
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
141
+ },
142
+ {
143
+ "chain_id": 1329,
144
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
145
+ },
146
+ {
147
+ "chain_id": 2201,
148
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
149
+ },
150
+ {
151
+ "chain_id": 4326,
152
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
153
+ },
154
+ {
155
+ "chain_id": 8453,
156
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
157
+ },
158
+ {
159
+ "chain_id": 10143,
160
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
161
+ },
162
+ {
163
+ "chain_id": 31612,
164
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
165
+ },
114
166
  {
115
167
  "chain_id": 42161,
116
168
  "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
169
+ },
170
+ {
171
+ "chain_id": 42220,
172
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
173
+ },
174
+ {
175
+ "chain_id": 43113,
176
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
177
+ },
178
+ {
179
+ "chain_id": 43114,
180
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
181
+ },
182
+ {
183
+ "chain_id": 80002,
184
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
185
+ },
186
+ {
187
+ "chain_id": 84532,
188
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
189
+ },
190
+ {
191
+ "chain_id": 421614,
192
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
193
+ },
194
+ {
195
+ "chain_id": 5042002,
196
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
197
+ },
198
+ {
199
+ "chain_id": 11142220,
200
+ "address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
117
201
  }
118
202
  ]
119
203
  },
@@ -0,0 +1,301 @@
1
+ {
2
+ "format": "candid-profile",
3
+ "format_version": 0,
4
+ "kind": "contract",
5
+ "name": "usdc-base-sepolia",
6
+ "origin": "third_party",
7
+ "language": "en",
8
+ "description": "USDC's EIP-3009 messages on Base Sepolia, a test network (spec section 15.9, experimental), with the usdc profile's words. TransferWithAuthorization and ReceiveWithAuthorization pay `to` once, by a signature that someone else submits (only the payee, for ReceiveWithAuthorization), and CancelAuthorization cancels one that is unused (EIP-3009; Circle stablecoin-evm, FiatTokenV2.sol). x402's `exact` scheme pays by TransferWithAuthorization by default (coinbase/x402, specs/schemes/exact/scheme_exact_evm.md). Only the messages are described: USDC's ABI names transferWithAuthorization, receiveWithAuthorization, cancelAuthorization and permit twice each, which the resolver refuses (O1). Base Sepolia's USDC signs under the domain name `USDC`, not the mainnets' `USD Coin`, and a profile binds one domain, so it has a profile of its own. Read on chain on 2026-10-30 (DOMAIN_SEPARATOR, decimals 6, the three type hashes); x402's own examples use it.",
9
+ "binds": {
10
+ "eip712": {
11
+ "domain": {
12
+ "name": "USDC",
13
+ "version": "2"
14
+ },
15
+ "types": {
16
+ "CancelAuthorization": [
17
+ {
18
+ "name": "authorizer",
19
+ "type": "address"
20
+ },
21
+ {
22
+ "name": "nonce",
23
+ "type": "bytes32"
24
+ }
25
+ ],
26
+ "ReceiveWithAuthorization": [
27
+ {
28
+ "name": "from",
29
+ "type": "address"
30
+ },
31
+ {
32
+ "name": "to",
33
+ "type": "address"
34
+ },
35
+ {
36
+ "name": "value",
37
+ "type": "uint256"
38
+ },
39
+ {
40
+ "name": "validAfter",
41
+ "type": "uint256"
42
+ },
43
+ {
44
+ "name": "validBefore",
45
+ "type": "uint256"
46
+ },
47
+ {
48
+ "name": "nonce",
49
+ "type": "bytes32"
50
+ }
51
+ ],
52
+ "TransferWithAuthorization": [
53
+ {
54
+ "name": "from",
55
+ "type": "address"
56
+ },
57
+ {
58
+ "name": "to",
59
+ "type": "address"
60
+ },
61
+ {
62
+ "name": "value",
63
+ "type": "uint256"
64
+ },
65
+ {
66
+ "name": "validAfter",
67
+ "type": "uint256"
68
+ },
69
+ {
70
+ "name": "validBefore",
71
+ "type": "uint256"
72
+ },
73
+ {
74
+ "name": "nonce",
75
+ "type": "bytes32"
76
+ }
77
+ ]
78
+ }
79
+ },
80
+ "deployments": [
81
+ {
82
+ "chain_id": 84532,
83
+ "address": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
84
+ }
85
+ ]
86
+ },
87
+ "annotations": [
88
+ {
89
+ "at": "TransferWithAuthorization",
90
+ "tag": "intent",
91
+ "args": {
92
+ "title": "Pay USDC by signature",
93
+ "template": "Send {value} from {from} to {to}, once. Valid after {validAfter}. Expires: {validBefore}."
94
+ }
95
+ },
96
+ {
97
+ "at": "TransferWithAuthorization",
98
+ "tag": "effect",
99
+ "args": {
100
+ "kind": "transfer",
101
+ "irreversible": true,
102
+ "grant": {
103
+ "to": "to",
104
+ "amount": "value",
105
+ "ends": [
106
+ "validBefore"
107
+ ]
108
+ }
109
+ }
110
+ },
111
+ {
112
+ "at": "TransferWithAuthorization(0).from",
113
+ "tag": "describe",
114
+ "args": {
115
+ "label": "From"
116
+ }
117
+ },
118
+ {
119
+ "at": "TransferWithAuthorization(0).to",
120
+ "tag": "describe",
121
+ "args": {
122
+ "label": "To"
123
+ }
124
+ },
125
+ {
126
+ "at": "TransferWithAuthorization(0).value",
127
+ "tag": "amount",
128
+ "args": {
129
+ "decimals": 6,
130
+ "symbol": "USDC"
131
+ }
132
+ },
133
+ {
134
+ "at": "TransferWithAuthorization(0).value",
135
+ "tag": "describe",
136
+ "args": {
137
+ "label": "Amount"
138
+ }
139
+ },
140
+ {
141
+ "at": "TransferWithAuthorization(0).validAfter",
142
+ "tag": "timestamp",
143
+ "args": {
144
+ "unit": "s",
145
+ "epoch": "unix"
146
+ }
147
+ },
148
+ {
149
+ "at": "TransferWithAuthorization(0).validAfter",
150
+ "tag": "describe",
151
+ "args": {
152
+ "label": "Valid after"
153
+ }
154
+ },
155
+ {
156
+ "at": "TransferWithAuthorization(0).validBefore",
157
+ "tag": "timestamp",
158
+ "args": {
159
+ "unit": "s",
160
+ "epoch": "unix",
161
+ "threshold": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
162
+ "message": "Never"
163
+ }
164
+ },
165
+ {
166
+ "at": "TransferWithAuthorization(0).validBefore",
167
+ "tag": "describe",
168
+ "args": {
169
+ "label": "Expires"
170
+ }
171
+ },
172
+ {
173
+ "at": "TransferWithAuthorization(0).nonce",
174
+ "tag": "describe",
175
+ "args": {
176
+ "label": "Nonce"
177
+ }
178
+ },
179
+ {
180
+ "at": "ReceiveWithAuthorization",
181
+ "tag": "intent",
182
+ "args": {
183
+ "title": "Pay USDC by signature, collected by the payee",
184
+ "template": "Send {value} from {from} to {to}, once; only {to} can submit it. Valid after {validAfter}. Expires: {validBefore}."
185
+ }
186
+ },
187
+ {
188
+ "at": "ReceiveWithAuthorization",
189
+ "tag": "effect",
190
+ "args": {
191
+ "kind": "transfer",
192
+ "irreversible": true,
193
+ "grant": {
194
+ "to": "to",
195
+ "amount": "value",
196
+ "ends": [
197
+ "validBefore"
198
+ ]
199
+ }
200
+ }
201
+ },
202
+ {
203
+ "at": "ReceiveWithAuthorization(0).from",
204
+ "tag": "describe",
205
+ "args": {
206
+ "label": "From"
207
+ }
208
+ },
209
+ {
210
+ "at": "ReceiveWithAuthorization(0).to",
211
+ "tag": "describe",
212
+ "args": {
213
+ "label": "To"
214
+ }
215
+ },
216
+ {
217
+ "at": "ReceiveWithAuthorization(0).value",
218
+ "tag": "amount",
219
+ "args": {
220
+ "decimals": 6,
221
+ "symbol": "USDC"
222
+ }
223
+ },
224
+ {
225
+ "at": "ReceiveWithAuthorization(0).value",
226
+ "tag": "describe",
227
+ "args": {
228
+ "label": "Amount"
229
+ }
230
+ },
231
+ {
232
+ "at": "ReceiveWithAuthorization(0).validAfter",
233
+ "tag": "timestamp",
234
+ "args": {
235
+ "unit": "s",
236
+ "epoch": "unix"
237
+ }
238
+ },
239
+ {
240
+ "at": "ReceiveWithAuthorization(0).validAfter",
241
+ "tag": "describe",
242
+ "args": {
243
+ "label": "Valid after"
244
+ }
245
+ },
246
+ {
247
+ "at": "ReceiveWithAuthorization(0).validBefore",
248
+ "tag": "timestamp",
249
+ "args": {
250
+ "unit": "s",
251
+ "epoch": "unix",
252
+ "threshold": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
253
+ "message": "Never"
254
+ }
255
+ },
256
+ {
257
+ "at": "ReceiveWithAuthorization(0).validBefore",
258
+ "tag": "describe",
259
+ "args": {
260
+ "label": "Expires"
261
+ }
262
+ },
263
+ {
264
+ "at": "ReceiveWithAuthorization(0).nonce",
265
+ "tag": "describe",
266
+ "args": {
267
+ "label": "Nonce"
268
+ }
269
+ },
270
+ {
271
+ "at": "CancelAuthorization",
272
+ "tag": "intent",
273
+ "args": {
274
+ "title": "Cancel a USDC payment signature",
275
+ "template": "Cancel the unused USDC payment signature of {authorizer} with nonce {nonce}."
276
+ }
277
+ },
278
+ {
279
+ "at": "CancelAuthorization",
280
+ "tag": "effect",
281
+ "args": {
282
+ "kind": "write",
283
+ "irreversible": true
284
+ }
285
+ },
286
+ {
287
+ "at": "CancelAuthorization(0).authorizer",
288
+ "tag": "describe",
289
+ "args": {
290
+ "label": "Signer of the payment"
291
+ }
292
+ },
293
+ {
294
+ "at": "CancelAuthorization(0).nonce",
295
+ "tag": "describe",
296
+ "args": {
297
+ "label": "Nonce"
298
+ }
299
+ }
300
+ ]
301
+ }