@heyanon-arp/sdk 0.0.37 → 0.0.39

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.
@@ -1,9 +1,9 @@
1
- import type { KeyLinkPayload, ScryptPasswordAttestation } from '../types/identity';
1
+ import type { Ed25519KeyLinkAttestation, KeyLinkPayload } from '../types/identity';
2
2
  /**
3
- * Build an `ARP-KEY-LINK-v1` attestation record signed via
4
- * `scrypt_password_proof`. Caller assembles the payload
5
- * (DID, both pubkeys, nonce, etc.); SDK produces the MAC
6
- * and wraps the record in the standard shape.
3
+ * Build an `ARP-KEY-LINK-v1` attestation signed via `ed25519_owner_key`:
4
+ * the agent's IDENTITY key signs `canonicalBytes(payload)`. The identity
5
+ * key is already proven at registration (the ARP-CHALLENGE-v1 step), so
6
+ * the key-link is self-certified with NO owner password / shared secret.
7
7
  *
8
8
  * Identity keys are immutable in alpha (no rotation); the KEY-LINK
9
9
  * attestation is the single owner-signed link between identity and
@@ -11,7 +11,13 @@ import type { KeyLinkPayload, ScryptPasswordAttestation } from '../types/identit
11
11
  */
12
12
  export declare function signKeyLinkAttestation(input: {
13
13
  payload: KeyLinkPayload;
14
- scryptKey: Uint8Array;
15
- scryptSaltId: string;
16
- }): ScryptPasswordAttestation<KeyLinkPayload>;
17
- export declare function verifyKeyLinkAttestation(attestation: ScryptPasswordAttestation<KeyLinkPayload>, scryptKey: Uint8Array): boolean;
14
+ identitySecretKey: Uint8Array;
15
+ }): Ed25519KeyLinkAttestation<KeyLinkPayload>;
16
+ /**
17
+ * Verify a key-link attestation against the identity key EMBEDDED in its
18
+ * payload (`payload.identity_public_key`). The caller is responsible for
19
+ * cross-checking that key against the agent DID / request body — this
20
+ * function only proves the payload was signed by the identity key it
21
+ * names. Returns false on any malformed input (no throw).
22
+ */
23
+ export declare function verifyKeyLinkAttestation(attestation: Ed25519KeyLinkAttestation<KeyLinkPayload>): boolean;
@@ -1,2 +1 @@
1
- export { deriveScryptKey, scryptPasswordProofSign, scryptPasswordProofVerify } from './scrypt-proof';
2
1
  export { signKeyLinkAttestation, verifyKeyLinkAttestation } from './attestation';
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * - did — `did:arp:<...>` parse/format + DID document types
9
9
  * - envelope — sign / verify envelope (steps 4-6 of protocol verification)
10
10
  * - challenge — ARP-CHALLENGE-v1 ownership proof (registration)
11
- * - attestation — scrypt key-link owner attestation
11
+ * - attestation — ed25519 key-link owner attestation
12
12
  * - server-chain — signed_message_hash, server_event_hash, audit walker
13
13
  * - settlement — canonical Solana program-id base58 constants
14
14
  * - purpose — domain separators (`ARP-*-v1`)
package/dist/index.js CHANGED
@@ -5,8 +5,6 @@ var utils = require('@noble/hashes/utils');
5
5
  var canonicalize = require('canonicalize');
6
6
  var base = require('@scure/base');
7
7
  var ed = require('@noble/ed25519');
8
- var hmac = require('@noble/hashes/hmac');
9
- var scrypt = require('@noble/hashes/scrypt');
10
8
  var web3_js = require('@solana/web3.js');
11
9
 
12
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -189,73 +187,43 @@ function verifyChallenge(challengeBytes, signature, identityPubkey) {
189
187
  if (signature.length !== 64) return false;
190
188
  return verify2(signature, buildSigningInput(challengeBytes), identityPubkey);
191
189
  }
192
-
193
- // src/types/identity.ts
194
- var OWNER_SIGNING_METHODS = ["scrypt_password_proof", "ed25519_owner_key", "totp+passphrase"];
195
- var SCRYPT_PARAMS = {
196
- N: 32768,
197
- r: 8,
198
- p: 1,
199
- dkLen: 32
200
- };
201
-
202
- // src/attestation/scrypt-proof.ts
203
- function deriveScryptKey(password, salt) {
204
- if (salt.length !== 16) {
205
- throw new Error(`deriveScryptKey: expected 16-byte salt, got ${salt.length}`);
190
+ var ED25519_SIG_PREFIX = "ed25519:";
191
+ function signKeyLinkAttestation(input) {
192
+ if (input.payload.purpose !== "ARP-KEY-LINK-v1") {
193
+ throw new Error(`signKeyLinkAttestation: expected purpose ARP-KEY-LINK-v1, got ${input.payload.purpose}`);
206
194
  }
207
- const passwordBytes = new TextEncoder().encode(password);
208
- return scrypt.scrypt(passwordBytes, salt, {
209
- N: SCRYPT_PARAMS.N,
210
- r: SCRYPT_PARAMS.r,
211
- p: SCRYPT_PARAMS.p,
212
- dkLen: SCRYPT_PARAMS.dkLen
213
- });
214
- }
215
- function scryptPasswordProofSign(payload, scryptKey) {
216
- if (scryptKey.length !== SCRYPT_PARAMS.dkLen) {
217
- throw new Error(`scryptPasswordProofSign: expected ${SCRYPT_PARAMS.dkLen}-byte scrypt key, got ${scryptKey.length}`);
195
+ if (input.payload.owner_signing_method !== "ed25519_owner_key") {
196
+ throw new Error(`signKeyLinkAttestation: this helper handles ed25519_owner_key only; got ${input.payload.owner_signing_method}`);
218
197
  }
219
- const digest = sha2.sha256(canonicalBytes(payload));
220
- const mac = hmac.hmac(sha2.sha256, scryptKey, digest);
221
- return base.base64.encode(mac);
222
- }
223
- function scryptPasswordProofVerify(payload, sigBase64, scryptKey) {
224
- if (scryptKey.length !== SCRYPT_PARAMS.dkLen) return false;
225
- let providedMac;
198
+ const sig = sign2(canonicalBytes(input.payload), input.identitySecretKey);
199
+ return { payload: input.payload, sig: `${ED25519_SIG_PREFIX}${base.base64.encode(sig)}` };
200
+ }
201
+ function verifyKeyLinkAttestation(attestation) {
202
+ const { payload, sig } = attestation;
203
+ if (payload.purpose !== "ARP-KEY-LINK-v1") return false;
204
+ if (payload.owner_signing_method !== "ed25519_owner_key") return false;
205
+ if (typeof sig !== "string" || !sig.startsWith(ED25519_SIG_PREFIX)) return false;
206
+ let sigBytes;
226
207
  try {
227
- providedMac = base.base64.decode(sigBase64);
208
+ sigBytes = base.base64.decode(sig.slice(ED25519_SIG_PREFIX.length));
228
209
  } catch {
229
210
  return false;
230
211
  }
231
- if (providedMac.length !== 32) return false;
232
- const digest = sha2.sha256(canonicalBytes(payload));
233
- const expectedMac = hmac.hmac(sha2.sha256, scryptKey, digest);
234
- return constantTimeEqualBytes(providedMac, expectedMac);
235
- }
236
- function constantTimeEqualBytes(a, b) {
237
- if (a.length !== b.length) return false;
238
- let diff = 0;
239
- for (let i = 0; i < a.length; i++) {
240
- diff |= a[i] ^ b[i];
241
- }
242
- return diff === 0;
243
- }
244
-
245
- // src/attestation/attestation.ts
246
- function signKeyLinkAttestation(input) {
247
- if (input.payload.purpose !== "ARP-KEY-LINK-v1") {
248
- throw new Error(`signKeyLinkAttestation: expected purpose ARP-KEY-LINK-v1, got ${input.payload.purpose}`);
212
+ if (sigBytes.length !== 64) return false;
213
+ let identityPubkey;
214
+ try {
215
+ identityPubkey = base58btcDecode(payload.identity_public_key);
216
+ } catch {
217
+ return false;
249
218
  }
250
- if (input.payload.owner_signing_method !== "scrypt_password_proof") {
251
- throw new Error(`signKeyLinkAttestation: this helper handles scrypt_password_proof only; got ${input.payload.owner_signing_method}`);
219
+ if (identityPubkey.length !== 32) return false;
220
+ let signingBytes;
221
+ try {
222
+ signingBytes = canonicalBytes(payload);
223
+ } catch {
224
+ return false;
252
225
  }
253
- const sig = scryptPasswordProofSign(input.payload, input.scryptKey);
254
- return { payload: input.payload, sig, scrypt_salt_id: input.scryptSaltId };
255
- }
256
- function verifyKeyLinkAttestation(attestation, scryptKey) {
257
- if (attestation.payload.purpose !== "ARP-KEY-LINK-v1") return false;
258
- return scryptPasswordProofVerify(attestation.payload, attestation.sig, scryptKey);
226
+ return verify2(sigBytes, signingBytes, identityPubkey);
259
227
  }
260
228
  function signedMessageHash(envelope) {
261
229
  const input = envelope.attachments === void 0 ? { protected: envelope.protected, body: envelope.body } : { protected: envelope.protected, body: envelope.body, attachments: envelope.attachments };
@@ -380,7 +348,7 @@ var SHA256_HEX_RE = /^sha256:[0-9a-f]{64}$/;
380
348
  function isSha256Hex(v) {
381
349
  return typeof v === "string" && SHA256_HEX_RE.test(v);
382
350
  }
383
- var ED25519_SIG_PREFIX = "ed25519:";
351
+ var ED25519_SIG_PREFIX2 = "ed25519:";
384
352
  var PROTOCOL_VERSIONS = ["arp/0.1"];
385
353
  var CURRENT_PROTOCOL_VERSION = PROTOCOL_VERSIONS[PROTOCOL_VERSIONS.length - 1];
386
354
 
@@ -569,6 +537,9 @@ function isReservedName(name) {
569
537
  function isValidAgentName(name) {
570
538
  return AGENT_NAME_REGEX.test(normalizeName(name));
571
539
  }
540
+
541
+ // src/types/identity.ts
542
+ var OWNER_SIGNING_METHODS = ["ed25519_owner_key", "totp+passphrase"];
572
543
  var LOCK_ACCOUNT_SIZE = 269;
573
544
  var LOCK_ACCOUNT_DISCRIMINATOR = new Uint8Array([8, 255, 36, 202, 210, 22, 57, 137]);
574
545
  var LOCK_STATE_NAMES = ["created", "canceled", "in_progress", "submitted", "paid", "revoked", "disputing", "dispute_resolved", "dispute_closed"];
@@ -1257,7 +1228,7 @@ exports.DelegationActions = DelegationActions;
1257
1228
  exports.DelegationOfferRejectionCodes = DelegationOfferRejectionCodes;
1258
1229
  exports.DelegationStates = DelegationStates;
1259
1230
  exports.DiscoverySorts = DiscoverySorts;
1260
- exports.ED25519_SIG_PREFIX = ED25519_SIG_PREFIX;
1231
+ exports.ED25519_SIG_PREFIX = ED25519_SIG_PREFIX2;
1261
1232
  exports.ESCROW_PDA_SEEDS = ESCROW_PDA_SEEDS;
1262
1233
  exports.ESCROW_PROGRAM_ID_BASE58 = ESCROW_PROGRAM_ID_BASE58;
1263
1234
  exports.ESCROW_RELEASE_METHODS = ESCROW_RELEASE_METHODS;
@@ -1291,7 +1262,6 @@ exports.RESERVED_NAMES = RESERVED_NAMES;
1291
1262
  exports.ReadModelStatuses = ReadModelStatuses;
1292
1263
  exports.ReceiptVerdicts = ReceiptVerdicts;
1293
1264
  exports.RelationshipStates = RelationshipStates;
1294
- exports.SCRYPT_PARAMS = SCRYPT_PARAMS;
1295
1265
  exports.SHA256_HEX_RE = SHA256_HEX_RE;
1296
1266
  exports.SLIP44_SOLANA = SLIP44_SOLANA;
1297
1267
  exports.SOLANA_CLUSTER_IDS = SOLANA_CLUSTER_IDS;
@@ -1333,7 +1303,6 @@ exports.deriveEventAuthorityPda = deriveEventAuthorityPda;
1333
1303
  exports.deriveLockId = deriveLockId;
1334
1304
  exports.deriveLockPda = deriveLockPda;
1335
1305
  exports.deriveOperatorAuthPda = deriveOperatorAuthPda;
1336
- exports.deriveScryptKey = deriveScryptKey;
1337
1306
  exports.deriveStakeVaultPda = deriveStakeVaultPda;
1338
1307
  exports.expiresAt = expiresAt;
1339
1308
  exports.fetchLockAccount = fetchLockAccount;
@@ -1370,8 +1339,6 @@ exports.parseDid = parseDid;
1370
1339
  exports.pollUntil = pollUntil;
1371
1340
  exports.resolveAsset = resolveAsset;
1372
1341
  exports.rfc3339 = rfc3339;
1373
- exports.scryptPasswordProofSign = scryptPasswordProofSign;
1374
- exports.scryptPasswordProofVerify = scryptPasswordProofVerify;
1375
1342
  exports.senderNonce = senderNonce;
1376
1343
  exports.serverEventHash = serverEventHash;
1377
1344
  exports.sign = sign2;
package/dist/index.mjs CHANGED
@@ -3,8 +3,6 @@ import { bytesToHex, randomBytes } from '@noble/hashes/utils';
3
3
  import canonicalize from 'canonicalize';
4
4
  import { base58, base64, base64urlnopad } from '@scure/base';
5
5
  import * as ed from '@noble/ed25519';
6
- import { hmac } from '@noble/hashes/hmac';
7
- import { scrypt } from '@noble/hashes/scrypt';
8
6
  import { PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
9
7
 
10
8
  // src/canonical/canonicalize.ts
@@ -164,73 +162,43 @@ function verifyChallenge(challengeBytes, signature, identityPubkey) {
164
162
  if (signature.length !== 64) return false;
165
163
  return verify2(signature, buildSigningInput(challengeBytes), identityPubkey);
166
164
  }
167
-
168
- // src/types/identity.ts
169
- var OWNER_SIGNING_METHODS = ["scrypt_password_proof", "ed25519_owner_key", "totp+passphrase"];
170
- var SCRYPT_PARAMS = {
171
- N: 32768,
172
- r: 8,
173
- p: 1,
174
- dkLen: 32
175
- };
176
-
177
- // src/attestation/scrypt-proof.ts
178
- function deriveScryptKey(password, salt) {
179
- if (salt.length !== 16) {
180
- throw new Error(`deriveScryptKey: expected 16-byte salt, got ${salt.length}`);
165
+ var ED25519_SIG_PREFIX = "ed25519:";
166
+ function signKeyLinkAttestation(input) {
167
+ if (input.payload.purpose !== "ARP-KEY-LINK-v1") {
168
+ throw new Error(`signKeyLinkAttestation: expected purpose ARP-KEY-LINK-v1, got ${input.payload.purpose}`);
181
169
  }
182
- const passwordBytes = new TextEncoder().encode(password);
183
- return scrypt(passwordBytes, salt, {
184
- N: SCRYPT_PARAMS.N,
185
- r: SCRYPT_PARAMS.r,
186
- p: SCRYPT_PARAMS.p,
187
- dkLen: SCRYPT_PARAMS.dkLen
188
- });
189
- }
190
- function scryptPasswordProofSign(payload, scryptKey) {
191
- if (scryptKey.length !== SCRYPT_PARAMS.dkLen) {
192
- throw new Error(`scryptPasswordProofSign: expected ${SCRYPT_PARAMS.dkLen}-byte scrypt key, got ${scryptKey.length}`);
170
+ if (input.payload.owner_signing_method !== "ed25519_owner_key") {
171
+ throw new Error(`signKeyLinkAttestation: this helper handles ed25519_owner_key only; got ${input.payload.owner_signing_method}`);
193
172
  }
194
- const digest = sha256(canonicalBytes(payload));
195
- const mac = hmac(sha256, scryptKey, digest);
196
- return base64.encode(mac);
197
- }
198
- function scryptPasswordProofVerify(payload, sigBase64, scryptKey) {
199
- if (scryptKey.length !== SCRYPT_PARAMS.dkLen) return false;
200
- let providedMac;
173
+ const sig = sign2(canonicalBytes(input.payload), input.identitySecretKey);
174
+ return { payload: input.payload, sig: `${ED25519_SIG_PREFIX}${base64.encode(sig)}` };
175
+ }
176
+ function verifyKeyLinkAttestation(attestation) {
177
+ const { payload, sig } = attestation;
178
+ if (payload.purpose !== "ARP-KEY-LINK-v1") return false;
179
+ if (payload.owner_signing_method !== "ed25519_owner_key") return false;
180
+ if (typeof sig !== "string" || !sig.startsWith(ED25519_SIG_PREFIX)) return false;
181
+ let sigBytes;
201
182
  try {
202
- providedMac = base64.decode(sigBase64);
183
+ sigBytes = base64.decode(sig.slice(ED25519_SIG_PREFIX.length));
203
184
  } catch {
204
185
  return false;
205
186
  }
206
- if (providedMac.length !== 32) return false;
207
- const digest = sha256(canonicalBytes(payload));
208
- const expectedMac = hmac(sha256, scryptKey, digest);
209
- return constantTimeEqualBytes(providedMac, expectedMac);
210
- }
211
- function constantTimeEqualBytes(a, b) {
212
- if (a.length !== b.length) return false;
213
- let diff = 0;
214
- for (let i = 0; i < a.length; i++) {
215
- diff |= a[i] ^ b[i];
216
- }
217
- return diff === 0;
218
- }
219
-
220
- // src/attestation/attestation.ts
221
- function signKeyLinkAttestation(input) {
222
- if (input.payload.purpose !== "ARP-KEY-LINK-v1") {
223
- throw new Error(`signKeyLinkAttestation: expected purpose ARP-KEY-LINK-v1, got ${input.payload.purpose}`);
187
+ if (sigBytes.length !== 64) return false;
188
+ let identityPubkey;
189
+ try {
190
+ identityPubkey = base58btcDecode(payload.identity_public_key);
191
+ } catch {
192
+ return false;
224
193
  }
225
- if (input.payload.owner_signing_method !== "scrypt_password_proof") {
226
- throw new Error(`signKeyLinkAttestation: this helper handles scrypt_password_proof only; got ${input.payload.owner_signing_method}`);
194
+ if (identityPubkey.length !== 32) return false;
195
+ let signingBytes;
196
+ try {
197
+ signingBytes = canonicalBytes(payload);
198
+ } catch {
199
+ return false;
227
200
  }
228
- const sig = scryptPasswordProofSign(input.payload, input.scryptKey);
229
- return { payload: input.payload, sig, scrypt_salt_id: input.scryptSaltId };
230
- }
231
- function verifyKeyLinkAttestation(attestation, scryptKey) {
232
- if (attestation.payload.purpose !== "ARP-KEY-LINK-v1") return false;
233
- return scryptPasswordProofVerify(attestation.payload, attestation.sig, scryptKey);
201
+ return verify2(sigBytes, signingBytes, identityPubkey);
234
202
  }
235
203
  function signedMessageHash(envelope) {
236
204
  const input = envelope.attachments === void 0 ? { protected: envelope.protected, body: envelope.body } : { protected: envelope.protected, body: envelope.body, attachments: envelope.attachments };
@@ -355,7 +323,7 @@ var SHA256_HEX_RE = /^sha256:[0-9a-f]{64}$/;
355
323
  function isSha256Hex(v) {
356
324
  return typeof v === "string" && SHA256_HEX_RE.test(v);
357
325
  }
358
- var ED25519_SIG_PREFIX = "ed25519:";
326
+ var ED25519_SIG_PREFIX2 = "ed25519:";
359
327
  var PROTOCOL_VERSIONS = ["arp/0.1"];
360
328
  var CURRENT_PROTOCOL_VERSION = PROTOCOL_VERSIONS[PROTOCOL_VERSIONS.length - 1];
361
329
 
@@ -544,6 +512,9 @@ function isReservedName(name) {
544
512
  function isValidAgentName(name) {
545
513
  return AGENT_NAME_REGEX.test(normalizeName(name));
546
514
  }
515
+
516
+ // src/types/identity.ts
517
+ var OWNER_SIGNING_METHODS = ["ed25519_owner_key", "totp+passphrase"];
547
518
  var LOCK_ACCOUNT_SIZE = 269;
548
519
  var LOCK_ACCOUNT_DISCRIMINATOR = new Uint8Array([8, 255, 36, 202, 210, 22, 57, 137]);
549
520
  var LOCK_STATE_NAMES = ["created", "canceled", "in_progress", "submitted", "paid", "revoked", "disputing", "dispute_resolved", "dispute_closed"];
@@ -1197,4 +1168,4 @@ var CliAuthTokenErrorCodes = {
1197
1168
  REQUIRED: "AUTH_TOKEN_REQUIRED"
1198
1169
  };
1199
1170
 
1200
- export { AGENT_BADGES, AGENT_NAME_REGEX, AGENT_TAG_REGEX, ASSET_DECIMALS_MAX, ASSET_DECIMALS_MIN, ASSET_SYMBOL_MAX_LEN, ASSET_SYMBOL_MIN_LEN, ASSET_WHITELIST, ASSOCIATED_TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID_BASE58, AgentBadges, BODY_TYPES, BodyTypes, CAIP19_REGEX, CLI_AUTH_TOKEN_ERROR_CODES, CLI_LOGIN_SESSION_STATES, CLI_LOGIN_SESSION_STORED_STATES, CREATE_LOCK_DISCRIMINATOR, CREATE_LOCK_NATIVE_DISCRIMINATOR, CURRENT_PROTOCOL_VERSION, CliAuthTokenErrorCodes, CliLoginSessionStates, DECIMAL_AMOUNT_REGEX, DECLINE_REASONS, DELEGATION_ACTIONS, DELEGATION_ACTIVE_STATES, DELEGATION_OFFER_REJECTION_CODES, DELEGATION_STATES, DEVNET_MINTS, DID_ARP_REGEX, DISCOVERY_SORTS, DelegationActions, DelegationOfferRejectionCodes, DelegationStates, DiscoverySorts, ED25519_SIG_PREFIX, ESCROW_PDA_SEEDS, ESCROW_PROGRAM_ID_BASE58, ESCROW_RELEASE_METHODS, EscrowReleaseMethods, HANDSHAKE_DECISIONS, HandshakeDecisions, INBOX_BLOCK_SCOPES, InboxBlockScopes, LIVE_RELATIONSHIP_STATE_NAMES, LOCK_ACCOUNT_DISCRIMINATOR, LOCK_ACCOUNT_SIZE, LOCK_STATE_NAMES, LOCK_TERMINAL_STATES, LockStates, LockTerminalStates, MAINNET_MINTS, MAX_CLOCK_SKEW_SECONDS, MAX_ENVELOPE_TTL_SECONDS, NATIVE_SOL_MINT, NATIVE_SOL_MINT_BASE58, NO_ARG_LIFECYCLE_INSTRUCTIONS, OWNER_SIGNING_METHODS, POST_COMMIT_ERROR_CODES, POST_COMMIT_ERROR_CODE_PREFIXES, PROTOCOL_VERSIONS, Purpose, READ_MODEL_STATUSES, RECEIPT_VERDICTS, RELATIONSHIP_STATE_NAMES, RESERVED_NAMES, ReadModelStatuses, ReceiptVerdicts, RelationshipStates, SCRYPT_PARAMS, SHA256_HEX_RE, SLIP44_SOLANA, SOLANA_CLUSTER_IDS, SPL_TOKEN_PROGRAM_ID, SPL_TOKEN_PROGRAM_ID_BASE58, SYSTEM_PROGRAM_ID_BASE58, TOKEN_2022_PROGRAM_ID_BASE58, WELL_KNOWN_ASSETS, WELL_KNOWN_ASSET_KEYS, WORK_LOG_STATES, WorkLogStates, base58btcDecode, base58btcEncode, buildAcceptLockIx, buildCancelLockIx, buildClaimExpiredWorkIx, buildClaimWorkPaymentIx, buildCloseDisputeIx, buildCreateLockIx, buildCreateLockIxData, buildLifecycleIxData, buildOpenDisputeIx, buildResolveDisputeIx, buildResolveDisputeIxData, buildSubmitWorkIx, bytes16ToDelegationId, canonicalBytes, canonicalJson, canonicalSha256Hex, decodeLockAccount, delegationIdToBytes16, deriveAta, deriveCollateralConfigPda, deriveConfigPda, deriveDelegationConditionHash, deriveDisputeResolutionPda, deriveEscrowPda, deriveEventAuthorityPda, deriveLockId, deriveLockPda, deriveOperatorAuthPda, deriveScryptKey, deriveStakeVaultPda, expiresAt, fetchLockAccount, findAssetByAssetId, findAssetMetaByMint, findFirstChainDivergence, formatDid, generateKeyPair, getPublicKey2 as getPublicKey, instructionDiscriminator, isAgentBadge, isAssetIdentifier, isBodyType, isCliLoginSessionWireState, isDecimalAmountString, isDeclineReason, isDelegationAction, isDelegationState, isEscrowReleaseMethod, isHandshakeDecision, isPostCommitErrorCode, isReadModelStatus, isReceiptVerdict, isRelationshipState, isReservedName, isSha256Hex, isValidAgentName, isValidDid, isWhitelistedAssetId, isWorkLogState, normalizeName, parseCaip19SolanaAssetId, parseDid, pollUntil, resolveAsset, rfc3339, scryptPasswordProofSign, scryptPasswordProofVerify, senderNonce, serverEventHash, sign2 as sign, signChallenge, signEnvelope, signKeyLinkAttestation, signedMessageHash, uuidV4, verify2 as verify, verifyChallenge, verifyEnvelope, verifyKeyLinkAttestation };
1171
+ export { AGENT_BADGES, AGENT_NAME_REGEX, AGENT_TAG_REGEX, ASSET_DECIMALS_MAX, ASSET_DECIMALS_MIN, ASSET_SYMBOL_MAX_LEN, ASSET_SYMBOL_MIN_LEN, ASSET_WHITELIST, ASSOCIATED_TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID_BASE58, AgentBadges, BODY_TYPES, BodyTypes, CAIP19_REGEX, CLI_AUTH_TOKEN_ERROR_CODES, CLI_LOGIN_SESSION_STATES, CLI_LOGIN_SESSION_STORED_STATES, CREATE_LOCK_DISCRIMINATOR, CREATE_LOCK_NATIVE_DISCRIMINATOR, CURRENT_PROTOCOL_VERSION, CliAuthTokenErrorCodes, CliLoginSessionStates, DECIMAL_AMOUNT_REGEX, DECLINE_REASONS, DELEGATION_ACTIONS, DELEGATION_ACTIVE_STATES, DELEGATION_OFFER_REJECTION_CODES, DELEGATION_STATES, DEVNET_MINTS, DID_ARP_REGEX, DISCOVERY_SORTS, DelegationActions, DelegationOfferRejectionCodes, DelegationStates, DiscoverySorts, ED25519_SIG_PREFIX2 as ED25519_SIG_PREFIX, ESCROW_PDA_SEEDS, ESCROW_PROGRAM_ID_BASE58, ESCROW_RELEASE_METHODS, EscrowReleaseMethods, HANDSHAKE_DECISIONS, HandshakeDecisions, INBOX_BLOCK_SCOPES, InboxBlockScopes, LIVE_RELATIONSHIP_STATE_NAMES, LOCK_ACCOUNT_DISCRIMINATOR, LOCK_ACCOUNT_SIZE, LOCK_STATE_NAMES, LOCK_TERMINAL_STATES, LockStates, LockTerminalStates, MAINNET_MINTS, MAX_CLOCK_SKEW_SECONDS, MAX_ENVELOPE_TTL_SECONDS, NATIVE_SOL_MINT, NATIVE_SOL_MINT_BASE58, NO_ARG_LIFECYCLE_INSTRUCTIONS, OWNER_SIGNING_METHODS, POST_COMMIT_ERROR_CODES, POST_COMMIT_ERROR_CODE_PREFIXES, PROTOCOL_VERSIONS, Purpose, READ_MODEL_STATUSES, RECEIPT_VERDICTS, RELATIONSHIP_STATE_NAMES, RESERVED_NAMES, ReadModelStatuses, ReceiptVerdicts, RelationshipStates, SHA256_HEX_RE, SLIP44_SOLANA, SOLANA_CLUSTER_IDS, SPL_TOKEN_PROGRAM_ID, SPL_TOKEN_PROGRAM_ID_BASE58, SYSTEM_PROGRAM_ID_BASE58, TOKEN_2022_PROGRAM_ID_BASE58, WELL_KNOWN_ASSETS, WELL_KNOWN_ASSET_KEYS, WORK_LOG_STATES, WorkLogStates, base58btcDecode, base58btcEncode, buildAcceptLockIx, buildCancelLockIx, buildClaimExpiredWorkIx, buildClaimWorkPaymentIx, buildCloseDisputeIx, buildCreateLockIx, buildCreateLockIxData, buildLifecycleIxData, buildOpenDisputeIx, buildResolveDisputeIx, buildResolveDisputeIxData, buildSubmitWorkIx, bytes16ToDelegationId, canonicalBytes, canonicalJson, canonicalSha256Hex, decodeLockAccount, delegationIdToBytes16, deriveAta, deriveCollateralConfigPda, deriveConfigPda, deriveDelegationConditionHash, deriveDisputeResolutionPda, deriveEscrowPda, deriveEventAuthorityPda, deriveLockId, deriveLockPda, deriveOperatorAuthPda, deriveStakeVaultPda, expiresAt, fetchLockAccount, findAssetByAssetId, findAssetMetaByMint, findFirstChainDivergence, formatDid, generateKeyPair, getPublicKey2 as getPublicKey, instructionDiscriminator, isAgentBadge, isAssetIdentifier, isBodyType, isCliLoginSessionWireState, isDecimalAmountString, isDeclineReason, isDelegationAction, isDelegationState, isEscrowReleaseMethod, isHandshakeDecision, isPostCommitErrorCode, isReadModelStatus, isReceiptVerdict, isRelationshipState, isReservedName, isSha256Hex, isValidAgentName, isValidDid, isWhitelistedAssetId, isWorkLogState, normalizeName, parseCaip19SolanaAssetId, parseDid, pollUntil, resolveAsset, rfc3339, senderNonce, serverEventHash, sign2 as sign, signChallenge, signEnvelope, signKeyLinkAttestation, signedMessageHash, uuidV4, verify2 as verify, verifyChallenge, verifyEnvelope, verifyKeyLinkAttestation };
@@ -68,8 +68,8 @@ export interface AgentRegisteredResponse {
68
68
  }
69
69
  /**
70
70
  * Public view of an ARP agent — signed reads (`GET /v1/agents/:did`)
71
- * and the profile `PATCH` response. Owner-only material (raw scrypt,
72
- * encrypted secrets) never appears here.
71
+ * and the profile `PATCH` response. Owner-only material (raw key
72
+ * material, encrypted secrets) never appears here.
73
73
  */
74
74
  export interface AgentPublic {
75
75
  did: string;
@@ -255,9 +255,9 @@ export interface ChallengeResponse {
255
255
  /**
256
256
  * Request body for `POST /v1/agents` (registration). The server DTO is
257
257
  * `RegisterAgentDto`; `ownerAttestation` mirrors the SDK
258
- * `ScryptPasswordAttestation<KeyLinkPayload>` wire shape but stays a
259
- * generic object here — its inner fields are verified by canonical-JSON
260
- * + HMAC at the server, not structurally.
258
+ * `Ed25519KeyLinkAttestation<KeyLinkPayload>` wire shape but stays a
259
+ * generic object here — its `sig` is verified against the payload's
260
+ * identity key (Ed25519) at the server, not structurally.
261
261
  */
262
262
  export interface RegisterAgentRequest {
263
263
  challengeId: string;
@@ -266,10 +266,7 @@ export interface RegisterAgentRequest {
266
266
  ownerAttestation: {
267
267
  payload: Record<string, unknown>;
268
268
  sig: string;
269
- scrypt_salt_id: string;
270
269
  };
271
- scryptKeyB64: string;
272
- scryptSaltB64: string;
273
270
  /**
274
271
  * Unique, immutable handle — lowercase `^[a-z0-9_]{3,32}$`
275
272
  * ({@link AGENT_NAME_REGEX}), REQUIRED. The server normalizes it and
@@ -1,16 +1,16 @@
1
1
  import type { Did } from './envelope';
2
2
  /**
3
- * Owner attestation methods per [00-core/identity.md](../../../00-core/identity.md).
4
- *
5
- * Only `scrypt_password_proof` is active (index 0); the others are
6
- * reserved placeholders for forward-compat. Backed by an `as const`
7
- * array so the server's attestation schema can source the active method
8
- * from `OWNER_SIGNING_METHODS[0]` instead of re-hardcoding the literal.
3
+ * Owner attestation methods. `ed25519_owner_key` is active (index 0):
4
+ * the agent's IDENTITY key self-signs the key-link, so there is NO
5
+ * separate owner password. `totp+passphrase` is a reserved placeholder
6
+ * for forward-compat. Backed by an `as const` array so the server's
7
+ * attestation schema sources the active method from
8
+ * `OWNER_SIGNING_METHODS[0]` instead of re-hardcoding the literal.
9
9
  */
10
- export declare const OWNER_SIGNING_METHODS: readonly ["scrypt_password_proof", "ed25519_owner_key", "totp+passphrase"];
10
+ export declare const OWNER_SIGNING_METHODS: readonly ["ed25519_owner_key", "totp+passphrase"];
11
11
  export type OwnerSigningMethod = (typeof OWNER_SIGNING_METHODS)[number];
12
12
  /**
13
- * `ARP-KEY-LINK-v1` payload — the canonical-JSON-hashed object an owner
13
+ * `ARP-KEY-LINK-v1` payload — the canonical-JSON-hashed object the owner
14
14
  * signs at registration. Carries the link between identity and settlement
15
15
  * keys plus owner identity / method metadata.
16
16
  */
@@ -25,20 +25,14 @@ export interface KeyLinkPayload {
25
25
  nonce: string;
26
26
  }
27
27
  /**
28
- * `scrypt_password_proof` the owner attestation envelope. The
29
- * signature is HMAC-SHA256(scrypt(password, salt), sha256(canonical(payload))),
30
- * base64-encoded. NOT an Ed25519 signature; verification is
31
- * server-side via the stored scrypt-derived key.
28
+ * `ed25519_owner_key` key-link attestation. The `sig` is the agent's
29
+ * IDENTITY Ed25519 key signing `canonicalBytes(payload)`, formatted as
30
+ * `ed25519:<base64(64-byte sig)>` the same convention as envelope
31
+ * signatures. SELF-VERIFYING: the verifier checks `sig` against the
32
+ * payload's `identity_public_key`; there is no shared secret and no
33
+ * password (the identity key is already challenge-proven at register).
32
34
  */
33
- export interface ScryptPasswordAttestation<TPayload extends KeyLinkPayload = KeyLinkPayload> {
35
+ export interface Ed25519KeyLinkAttestation<TPayload extends KeyLinkPayload = KeyLinkPayload> {
34
36
  payload: TPayload;
35
37
  sig: string;
36
- scrypt_salt_id: string;
37
38
  }
38
- /** Standard scrypt parameters used for owner password proofs. */
39
- export declare const SCRYPT_PARAMS: {
40
- readonly N: 32768;
41
- readonly r: 8;
42
- readonly p: 1;
43
- readonly dkLen: 32;
44
- };
@@ -19,5 +19,5 @@ export { CLI_LOGIN_SESSION_STORED_STATES, CLI_LOGIN_SESSION_STATES, CliLoginSess
19
19
  export type { AssetIdentifierWire, DelegationPublic, DisputeResolutionPublic, ReceiptPublic, RelationshipPublic, WorkLogPublic, EventPublic, IngestResult, SenderSequenceResponse, InboxUnblockResult, ListRelationshipsQuery, ListInboxQuery, ListEventsQuery, ListDelegationsQuery, ListWorkLogsQuery, ListReceiptsQuery, } from './read-model';
20
20
  export type { AcceptPrefs, AcceptCurrency, AgentRegisteredResponse, AgentPublic, UpdateAgentBody, RegisterAgentRequest, ChallengeResponse, ReputationScores, ReputationCounters, AgentReputation, AssetVolume, AgentSettlementVolume, AgentStatsRates, AgentStats, } from './agent';
21
21
  export { AGENT_TAG_REGEX, AGENT_NAME_REGEX, RESERVED_NAMES, isReservedName, isValidAgentName, normalizeName } from './agent';
22
- export type { OwnerSigningMethod, KeyLinkPayload, ScryptPasswordAttestation } from './identity';
23
- export { SCRYPT_PARAMS, OWNER_SIGNING_METHODS } from './identity';
22
+ export type { OwnerSigningMethod, KeyLinkPayload, Ed25519KeyLinkAttestation } from './identity';
23
+ export { OWNER_SIGNING_METHODS } from './identity';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@heyanon-arp/sdk",
3
- "version": "0.0.37",
4
- "description": "TypeScript SDK for the Agent Relationship Protocol — canonical JSON, Ed25519 envelope sign/verify, did:arp identity, scrypt key attestation, chain-audit helpers.",
3
+ "version": "0.0.39",
4
+ "description": "TypeScript SDK for the Agent Relationship Protocol — canonical JSON, Ed25519 envelope sign/verify, did:arp identity, Ed25519 owner key-link attestation, chain-audit helpers.",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "arp",
@@ -1,28 +0,0 @@
1
- /**
2
- * Derive the scrypt key from an owner's password + salt. Uses the
3
- * standard parameters: N=32768, r=8, p=1, dkLen=32. Designed to be
4
- * computed once at owner registration time and stored encrypted-at-rest;
5
- * subsequent attestation verification recomputes the HMAC, not scrypt.
6
- *
7
- * Synchronous variant is intentional — keys derive at low frequency
8
- * (once per owner registration); the worst case is a few hundred ms
9
- * which is acceptable. Async variants can be layered on top by the
10
- * consumer if needed.
11
- */
12
- export declare function deriveScryptKey(password: string, salt: Uint8Array): Uint8Array;
13
- /**
14
- * Compute the scrypt-password-proof signature over the canonical
15
- * payload bytes, returning the base64-encoded MAC.
16
- *
17
- * Steps per [00-core/identity.md](../../../00-core/identity.md):
18
- * 1. payload_digest = sha256(canonical_json(payload))
19
- * 2. mac = HMAC-SHA256(scrypt_key, payload_digest)
20
- * 3. sig = base64(mac)
21
- */
22
- export declare function scryptPasswordProofSign(payload: unknown, scryptKey: Uint8Array): string;
23
- /**
24
- * Verify a scrypt-password-proof signature. Constant-time compare on
25
- * MAC bytes — never compares strings directly because base64 decoding
26
- * normalises some inputs which would mask differences.
27
- */
28
- export declare function scryptPasswordProofVerify(payload: unknown, sigBase64: string, scryptKey: Uint8Array): boolean;