inamprotocol 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -40,9 +40,39 @@ const receipt = await worker.submitWork(poster.did, {
40
40
  await poster.acceptWork(receipt); // finalizes the receipt and auto-completes the job
41
41
  ```
42
42
 
43
+ `poster.cancelJob(job.jobId)` cancels a not-yet-completed job (poster only); `client.getJob(id)` / `client.searchJobs({ capability, status })` / `client.listOffers(jobId)` round out discovery.
44
+
45
+ ### External identity linking (challenge-response)
46
+
47
+ Linking a key-derived external identity (`agentpass_id` / `aitp_id` / `passport_id`; SPEC.md §2.1) requires proving control of that external key via a single-use, ~60s challenge — a bare claim is no longer enough. `a2a_endpoint` isn't key-derived, so it skips straight to `linkIdentity(protocol, value)`.
48
+
49
+ ```ts
50
+ // externalKeypair stands in for whatever key AgentPass/AITP/Passport Alliance
51
+ // already issued this agent -- not an INAM keypair.
52
+ const challenge = await client.requestLinkChallenge("agentpass_id", toBase64(externalKeypair.publicKey), "ed25519");
53
+ const proof = toBase64(sign(fromHex(challenge.challenge), externalKeypair.privateKey));
54
+ await client.completeLink("agentpass_id", "ap_my_external_id", challenge.challengeId, proof);
55
+ ```
56
+
57
+ ### Verification (independent attestation)
58
+
59
+ A third party — anyone but the receipt's own worker (`agentB`) — can attest that a finalized receipt's output actually holds up (SPEC.md §12), feeding a reputation boost:
60
+
61
+ ```ts
62
+ const verification = await verifierClient.submitVerification({
63
+ receiptId: receipt.receiptId,
64
+ method: "deterministic", // or "agent_attestation"
65
+ outputHash: receipt.result.outputHash,
66
+ result: "verified", // or "rejected"
67
+ });
68
+
69
+ await verifierClient.getVerification(verification.verificationId);
70
+ await verifierClient.listReceiptVerifications(receipt.receiptId);
71
+ ```
72
+
43
73
  ## What's exported
44
74
 
45
- `InamClient`, `generateKeypair`/`keypairFromPrivateKey`/`publicKeyToDid`/`didToPublicKey`/`sign`/`verify`/`sha256Hex`, `canonicalize` (the canonical-JSON serializer every INAM signature is computed over), `computeReceiptId`/`buildSignableContent`, and the full set of wire-format types (`AgentRecord`, `ExecutionReceipt`, `JobRecord`, `JobOffer`, `ReputationResult`, ...).
75
+ `InamClient`, `generateKeypair`/`keypairFromPrivateKey`/`publicKeyToDid`/`didToPublicKey`/`sign`/`verify`/`verifyRawEd25519`/`sha256Hex`, `generateP256Keypair`/`p256Sign`/`p256Verify` (used for external-identity link-challenge proofs, SPEC.md §2.1), `canonicalize` (the canonical-JSON serializer every INAM signature is computed over), `computeReceiptId`/`buildSignableContent`, `computeVerificationId`/`buildSignableVerificationContent`, and the full set of wire-format types (`AgentRecord`, `ExecutionReceipt`, `JobRecord`, `JobOffer`, `ReputationResult`, `LinkChallenge`, `VerificationRecord`, ...).
46
76
 
47
77
  ## Building from source
48
78
 
@@ -4,5 +4,16 @@
4
4
  * not handle every JCS number-formatting edge case, but it is deterministic
5
5
  * for the plain string/number/boolean/array/object shapes used by Inam Protocol's own
6
6
  * schemas, which is all that's required for our signer and verifier to agree.
7
+ *
8
+ * Number formatting here (via native `JSON.stringify`) already follows the
9
+ * ECMA-262 `Number::toString` algorithm, which is what
10
+ * sdk-python/inamprotocol/canonical.py's `_format_number` was written to
11
+ * replicate byte-for-byte after a real cross-language signature failure
12
+ * (`score: 1.0` verified in Python, rejected here, because Python's own
13
+ * `json.dumps` renders it "1.0" where this renders it "1"). One gap native
14
+ * `JSON.stringify` has that Python's fix doesn't: `JSON.stringify(NaN)` and
15
+ * `JSON.stringify(Infinity)` both silently produce the string `"null"`
16
+ * rather than erroring, which would corrupt a signature without any error on
17
+ * either side — guarded against explicitly below.
7
18
  */
8
19
  export declare function canonicalize(value: unknown): string;
@@ -4,11 +4,25 @@
4
4
  * not handle every JCS number-formatting edge case, but it is deterministic
5
5
  * for the plain string/number/boolean/array/object shapes used by Inam Protocol's own
6
6
  * schemas, which is all that's required for our signer and verifier to agree.
7
+ *
8
+ * Number formatting here (via native `JSON.stringify`) already follows the
9
+ * ECMA-262 `Number::toString` algorithm, which is what
10
+ * sdk-python/inamprotocol/canonical.py's `_format_number` was written to
11
+ * replicate byte-for-byte after a real cross-language signature failure
12
+ * (`score: 1.0` verified in Python, rejected here, because Python's own
13
+ * `json.dumps` renders it "1.0" where this renders it "1"). One gap native
14
+ * `JSON.stringify` has that Python's fix doesn't: `JSON.stringify(NaN)` and
15
+ * `JSON.stringify(Infinity)` both silently produce the string `"null"`
16
+ * rather than erroring, which would corrupt a signature without any error on
17
+ * either side — guarded against explicitly below.
7
18
  */
8
19
  export function canonicalize(value) {
9
20
  return stringify(value);
10
21
  }
11
22
  function stringify(value) {
23
+ if (typeof value === "number" && !Number.isFinite(value)) {
24
+ throw new Error(`Cannot canonicalize non-finite number: ${value}`);
25
+ }
12
26
  if (value === null || typeof value !== "object") {
13
27
  return JSON.stringify(value);
14
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACpD,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,0CAA0C,KAAK,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACpD,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inamprotocol",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Reference TypeScript/JavaScript SDK for the INAM Protocol — agent identity, execution receipts, jobs, and reputation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -46,6 +46,7 @@
46
46
  "bs58": "^6.0.0"
47
47
  },
48
48
  "devDependencies": {
49
+ "@types/node": "^22.5.0",
49
50
  "typescript": "^5.5.4"
50
51
  }
51
52
  }