cascrow-signer 0.2.0 → 0.3.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 +14 -0
- package/MIGRATION.md +11 -3
- package/README.md +3 -3
- package/dist/actions.d.ts +4 -1
- package/dist/actions.js +14 -4
- package/dist/api.d.ts +1 -1
- package/dist/api.js +1 -1
- package/dist/checks.js +1 -1
- package/dist/journal.d.ts +9 -1
- package/dist/journal.js +15 -3
- package/dist/reason.d.ts +4 -0
- package/dist/reason.js +27 -0
- package/dist/remote.d.ts +1 -0
- package/dist/remote.js +1 -0
- package/dist/tools.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0 — 2026-10-21
|
|
4
|
+
|
|
5
|
+
- **`object` commits to a salted hash of the reason.** What goes on chain is now
|
|
6
|
+
`keccak256(salt ‖ utf8(reason))` (= `solidityPackedKeccak256(["bytes32","string"], [salt, reason])`),
|
|
7
|
+
with a salt of 32 random bytes made on this machine; 0.2.0 sent `keccak256(utf8(reason))`,
|
|
8
|
+
and that hash stands on two public ledgers for good (the `Objected` event, and cascrow's
|
|
9
|
+
audit memo on the XRP Ledger), where a short reason could be confirmed by hashing guesses.
|
|
10
|
+
The result of `object` carries `reason`, `reasonSalt` and `reasonHash`, and the spending
|
|
11
|
+
journal keeps the same three on the `object` reservation (`objection`). Keep the salt with
|
|
12
|
+
the reason: without it nobody, you included, can show later which reason the hash commits
|
|
13
|
+
to. Neither the reason nor the salt is sent to cascrow — `prepare` still gets only the hash.
|
|
14
|
+
The contract does not read the hash; nothing else changes. Every `cascrow-signer` pin is now
|
|
15
|
+
`cascrow-signer@0.3.0`.
|
|
16
|
+
|
|
3
17
|
## 0.2.0 — 2026-10-19
|
|
4
18
|
|
|
5
19
|
- **Upgrade required to link a wallet** (cascrow SEC-145). cascrow's wallet challenge is now a
|
package/MIGRATION.md
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
# Migrating to cascrow-signer
|
|
2
2
|
|
|
3
|
+
## From 0.2.0 to 0.3.0
|
|
4
|
+
|
|
5
|
+
Nothing to do: the keystore, the escrow book, the policy and the journal are compatible both
|
|
6
|
+
ways (0.2.0 reads a 0.3.0 journal and ignores the new field). What changes is `object`: the
|
|
7
|
+
hash it puts on chain is salted — `keccak256(salt ‖ utf8(reason))` — and its result returns
|
|
8
|
+
`reasonSalt`. Keep the salt with the reason (the journal keeps a copy); an objection made with
|
|
9
|
+
0.2.0 committed to the unsalted `keccak256(utf8(reason))`, which stays as it is on chain.
|
|
10
|
+
|
|
3
11
|
## From 0.1.0 to 0.2.0
|
|
4
12
|
|
|
5
13
|
cascrow's wallet challenge changed to a Sign-In with Ethereum (EIP-4361) message (SEC-145)
|
|
6
14
|
that names the wallet being linked, so the challenge request has to carry that address. 0.1.0
|
|
7
15
|
asks without it, and `link` fails with
|
|
8
|
-
`address is required: … update to 0.
|
|
16
|
+
`address is required: … update to 0.3.0 (npx cascrow-signer@0.3.0 link) … [CHALLENGE_ADDRESS_REQUIRED]`
|
|
9
17
|
(HTTP 400) before anything is signed — safe, but `link` no longer works until you upgrade:
|
|
10
|
-
`npx cascrow-signer@0.
|
|
18
|
+
`npx cascrow-signer@0.3.0 link`. The keystore, the escrow book and your policy file are
|
|
11
19
|
compatible; what else changes:
|
|
12
20
|
|
|
13
21
|
- **The spending journal** (`journal.jsonl`) is upgraded to a MAC-chained format on the first
|
|
@@ -46,7 +54,7 @@ do not link the old address again (cascrow refuses it anyway).
|
|
|
46
54
|
|---|---|
|
|
47
55
|
| `cascrow_escrow_fund { agentPrivateKey, … }` | `cascrow_signer_fund { milestoneId }` in this package's MCP server |
|
|
48
56
|
| `client.escrowFund({ privateKey, … })` | `createSigner(configFromEnv(process.env, io)).fund({ milestoneId })` |
|
|
49
|
-
| `cascrow escrow-fund --private-key …` | `npx cascrow-signer@0.
|
|
57
|
+
| `cascrow escrow-fund --private-key …` | `npx cascrow-signer@0.3.0 fund --milestone <id>` |
|
|
50
58
|
| the wallet cascrow generated at registration | `cascrow-signer init` + `cascrow-signer link` |
|
|
51
59
|
|
|
52
60
|
## v2 (RLUSD) escrows
|
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ it signs against what it knows independently of cascrow.
|
|
|
15
15
|
Install a pinned version — never `@latest` for a tool that holds money:
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
|
-
npx cascrow-signer@0.
|
|
18
|
+
npx cascrow-signer@0.3.0 help
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
> **Status: released (0.1.0, on npm since 2026-09-27).** MilestoneEscrowV3 is deployed on
|
|
@@ -58,7 +58,7 @@ read. There is no OS-keychain integration on purpose (native dependency, supply
|
|
|
58
58
|
cascrow-signer fund --milestone <id> # one transaction, value = amount, no approve
|
|
59
59
|
cascrow-signer claims # live claims on your escrows, read from the chain
|
|
60
60
|
cascrow-signer watch --exec ./page-me.sh # alarm for every claim whose window is open — and when it is blind
|
|
61
|
-
cascrow-signer object --escrow 0x… --reason "Criterion 2 is not met: …"
|
|
61
|
+
cascrow-signer object --escrow 0x… --reason "Criterion 2 is not met: …" # result: reasonHash + reasonSalt — keep the salt
|
|
62
62
|
cascrow-signer release --escrow 0x…
|
|
63
63
|
cascrow-signer extend-deadline --escrow 0x… --new-deadline 1767225600
|
|
64
64
|
```
|
|
@@ -134,7 +134,7 @@ on a terminal with `cascrow-signer policy set … --allow-agent-return-funds`.
|
|
|
134
134
|
|
|
135
135
|
```json
|
|
136
136
|
{ "mcpServers": { "cascrow-signer": {
|
|
137
|
-
"command": "npx", "args": ["cascrow-signer@0.
|
|
137
|
+
"command": "npx", "args": ["cascrow-signer@0.3.0", "mcp"],
|
|
138
138
|
"env": { "CASCROW_SIGNER_NETWORK": "testnet", "CASCROW_API_KEY": "csk_…",
|
|
139
139
|
"CASCROW_KEYSTORE_PASSPHRASE_FILE": "/home/me/.cascrow/pass" } } } }
|
|
140
140
|
```
|
package/dist/actions.d.ts
CHANGED
|
@@ -49,7 +49,10 @@ export declare function localProofHash(milestoneId: string, ev: EvidenceInput):
|
|
|
49
49
|
export type EscrowActionInput = {
|
|
50
50
|
escrowId?: string;
|
|
51
51
|
milestoneId?: string;
|
|
52
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* object: the objection reason. On chain goes keccak256(salt ‖ utf8(reason)) with a
|
|
54
|
+
* salt made here (reason.ts); the reason and the salt never leave this machine.
|
|
55
|
+
*/
|
|
53
56
|
reason?: string;
|
|
54
57
|
/** extendDeadline: unix seconds. */
|
|
55
58
|
newDeadline?: string | number;
|
package/dist/actions.js
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* refusal, never read as "down" (post-review G1/H2).
|
|
16
16
|
*/
|
|
17
17
|
import fs from "node:fs";
|
|
18
|
-
import { ZeroAddress, formatEther, getAddress,
|
|
18
|
+
import { ZeroAddress, formatEther, getAddress, parseEther, sha256 } from "ethers";
|
|
19
|
+
import { newReasonSalt, objectionReasonHash } from "./reason.js";
|
|
19
20
|
import { SignerError, refuse } from "./errors.js";
|
|
20
21
|
import { ACTION_FN, PER_ESCROW_ACTIONS, decodeCall, encodeCall } from "./calldata.js";
|
|
21
22
|
import { BOOK_BOUND_ACTIONS, checkEscrowAction, checkFund, checkMatchesLocal, checkPreparedEnvelope, checkWithdraw, fundTermsFrom } from "./checks.js";
|
|
@@ -275,7 +276,12 @@ export async function escrowAction(ctx, action, input) {
|
|
|
275
276
|
const notes = [];
|
|
276
277
|
const c = chainCtx(ctx);
|
|
277
278
|
// Arguments, computed locally.
|
|
278
|
-
|
|
279
|
+
// object: a fresh salt per objection, made here, never sent — only the salted hash
|
|
280
|
+
// goes to prepare and on chain, and the result and the journal keep the salt.
|
|
281
|
+
if (action === "object" && !input.reason)
|
|
282
|
+
refuse("INPUT", "object needs a reason");
|
|
283
|
+
const reasonSalt = action === "object" ? newReasonSalt() : null;
|
|
284
|
+
const reasonHash = action === "object" ? objectionReasonHash(input.reason, reasonSalt) : null;
|
|
279
285
|
const newDeadline = action === "extendDeadline" ? (input.newDeadline !== undefined ? BigInt(input.newDeadline) : refuse("INPUT", "extendDeadline needs newDeadline")) : null;
|
|
280
286
|
let proofHash = null;
|
|
281
287
|
if (action === "submitClaim") {
|
|
@@ -359,10 +365,14 @@ export async function escrowAction(ctx, action, input) {
|
|
|
359
365
|
const entry = bookBound ? book.find(escrowId, ctx.net.chainId, ctx.net.address) : input.milestoneId ? null : findIn(readBookLoosely(ctx, book, notes));
|
|
360
366
|
checkEscrowAction(action, me, e, head.timestamp, { book: entry, newDeadline, proofHash, reasonHash, ...(limits ? { maxDeadlineSeconds: limits.maxDeadlineSeconds } : {}) });
|
|
361
367
|
noteJournalIntegrity(ctx, journal, notes);
|
|
362
|
-
const
|
|
368
|
+
const objection = reasonHash && reasonSalt ? { reason: input.reason, reasonSalt, reasonHash } : undefined;
|
|
369
|
+
const rid = journal.reserve(action, escrowId, BigInt(0), head.timestamp, objection);
|
|
363
370
|
const sent = await sendSigned(c, key, journal, rid, { to: ctx.net.address, data, value: BigInt(0) });
|
|
364
371
|
if (sent.note)
|
|
365
372
|
notes.push(sent.note);
|
|
373
|
+
if (objection) {
|
|
374
|
+
notes.push("Keep reasonSalt with your reason (also in this signer's journal): only keccak256(reasonSalt ‖ utf8(reason)) went on chain, and without the salt nobody can show later that it is this reason. cascrow received neither.");
|
|
375
|
+
}
|
|
366
376
|
const milestoneId = input.milestoneId ?? entry?.milestoneId ?? null;
|
|
367
377
|
const reported = await report(ctx, milestoneId, sent.txHash, notes);
|
|
368
378
|
return {
|
|
@@ -373,7 +383,7 @@ export async function escrowAction(ctx, action, input) {
|
|
|
373
383
|
reported,
|
|
374
384
|
from: me,
|
|
375
385
|
...(proofHash ? { proofHash } : {}),
|
|
376
|
-
...(
|
|
386
|
+
...(objection ?? {}),
|
|
377
387
|
notes,
|
|
378
388
|
};
|
|
379
389
|
});
|
package/dist/api.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export { checkChallenge, buildChallengeMessage, challengeStatement, CHALLENGE_AU
|
|
|
14
14
|
export type { ChallengeExpectation, ChallengeFields, ChallengePurpose, LinkOptions } from "./link.js";
|
|
15
15
|
export { localProofHash } from "./actions.js";
|
|
16
16
|
export { resolveNetwork, PUBLIC_NETWORKS } from "./network.js";
|
|
17
|
-
export declare const SIGNER_VERSION = "0.
|
|
17
|
+
export declare const SIGNER_VERSION = "0.3.0";
|
|
18
18
|
/** Create the keystore and the spending journal. Does not need a network or cascrow. */
|
|
19
19
|
export declare function initSigner(home: string, passphrase: string, opts?: {
|
|
20
20
|
scryptN?: number;
|
package/dist/api.js
CHANGED
|
@@ -29,7 +29,7 @@ export { checkAcceptance } from "./acceptance.js";
|
|
|
29
29
|
export { checkChallenge, buildChallengeMessage, challengeStatement, CHALLENGE_AUDIENCE } from "./link.js";
|
|
30
30
|
export { localProofHash } from "./actions.js";
|
|
31
31
|
export { resolveNetwork, PUBLIC_NETWORKS } from "./network.js";
|
|
32
|
-
export const SIGNER_VERSION = "0.
|
|
32
|
+
export const SIGNER_VERSION = "0.3.0";
|
|
33
33
|
/** Create the keystore and the spending journal. Does not need a network or cascrow. */
|
|
34
34
|
export async function initSigner(home, passphrase, opts = {}) {
|
|
35
35
|
ensureHome(home);
|
package/dist/checks.js
CHANGED
|
@@ -236,7 +236,7 @@ export function checkEscrowAction(action, me, e, chainNowSec, opts) {
|
|
|
236
236
|
if (action === "submitClaim" && !/^0x[0-9a-f]{64}$/.test(lc(opts.proofHash ?? "")))
|
|
237
237
|
r.push("proofHash must be a 32-byte hex value (the manifestHash of a sealed submission)");
|
|
238
238
|
if (action === "object" && !/^0x[0-9a-f]{64}$/.test(lc(opts.reasonHash ?? "")))
|
|
239
|
-
r.push("reasonHash must be a 32-byte hex value");
|
|
239
|
+
r.push("reasonHash must be a 32-byte hex value (keccak256(salt ‖ utf8(reason)))");
|
|
240
240
|
fail("CHECK_FAILED", r);
|
|
241
241
|
}
|
|
242
242
|
export function checkWithdraw(me, credit) {
|
package/dist/journal.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ export declare const DAY_SECONDS: number;
|
|
|
4
4
|
export declare const JOURNAL_VERSION = 2;
|
|
5
5
|
/** The only transaction fields a `signed` line may carry — what was signed, never the signature. */
|
|
6
6
|
export declare const UNSIGNED_TX_FIELDS: readonly string[];
|
|
7
|
+
/** What `object` committed to on chain: reasonHash = keccak256(reasonSalt ‖ utf8(reason)). */
|
|
8
|
+
export type ObjectionRecord = {
|
|
9
|
+
reason: string;
|
|
10
|
+
reasonSalt: string;
|
|
11
|
+
reasonHash: string;
|
|
12
|
+
};
|
|
7
13
|
export type Reservation = {
|
|
8
14
|
id: string;
|
|
9
15
|
action: string;
|
|
@@ -20,6 +26,8 @@ export type Reservation = {
|
|
|
20
26
|
unknown: boolean;
|
|
21
27
|
/** A v1 line: unauthenticated. Counts toward the limit, never releases, never re-signed. */
|
|
22
28
|
legacy: boolean;
|
|
29
|
+
/** object (0.3.0 on): the reason, salt and hash it committed to; null otherwise. */
|
|
30
|
+
objection: ObjectionRecord | null;
|
|
23
31
|
};
|
|
24
32
|
export type JournalState =
|
|
25
33
|
/** No journal file. */
|
|
@@ -92,7 +100,7 @@ export declare class KeyedJournal {
|
|
|
92
100
|
verify(): VerifiedJournal;
|
|
93
101
|
/** The verified journal for a decision about money: refused unless the chain is unbroken. */
|
|
94
102
|
verifyForSpending(): VerifiedJournal;
|
|
95
|
-
reserve(action: string, escrowId: string | null, amountWei: bigint, nowSec: number): string;
|
|
103
|
+
reserve(action: string, escrowId: string | null, amountWei: bigint, nowSec: number, objection?: ObjectionRecord): string;
|
|
96
104
|
signed(id: string, hash: string, nonce: number, tx: Record<string, unknown>): void;
|
|
97
105
|
sent(id: string, hash: string): void;
|
|
98
106
|
unknown(id: string, hash: string, reason: string): void;
|
package/dist/journal.js
CHANGED
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
* is refused — the limit is not guessed.
|
|
43
43
|
*
|
|
44
44
|
* The journal never holds a signature or a signed transaction: `signed` keeps the
|
|
45
|
-
* unsigned fields only (`UNSIGNED_TX_FIELDS`).
|
|
45
|
+
* unsigned fields only (`UNSIGNED_TX_FIELDS`). An `object` reservation carries the
|
|
46
|
+
* objection's reason, its salt and its hash (`objection`, 0.3.0): the salt exists
|
|
47
|
+
* nowhere else, and without it the on-chain hash proves nothing.
|
|
46
48
|
*/
|
|
47
49
|
import fs from "node:fs";
|
|
48
50
|
import path from "node:path";
|
|
@@ -58,6 +60,15 @@ const ZERO_MAC = "0".repeat(64);
|
|
|
58
60
|
export const UNSIGNED_TX_FIELDS = Object.freeze([
|
|
59
61
|
"chainId", "nonce", "to", "data", "value", "gasLimit", "type", "maxFeePerGas", "maxPriorityFeePerGas", "gasPrice",
|
|
60
62
|
]);
|
|
63
|
+
/** A reserve line's `objection`, if it is well-formed; anything else reads as none (it decides no money). */
|
|
64
|
+
function objectionOf(v) {
|
|
65
|
+
if (!v || typeof v !== "object")
|
|
66
|
+
return null;
|
|
67
|
+
const o = v;
|
|
68
|
+
return typeof o.reason === "string" && typeof o.reasonSalt === "string" && typeof o.reasonHash === "string"
|
|
69
|
+
? { reason: o.reason, reasonSalt: o.reasonSalt, reasonHash: o.reasonHash }
|
|
70
|
+
: null;
|
|
71
|
+
}
|
|
61
72
|
const inProcess = new Map();
|
|
62
73
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
63
74
|
function pidAlive(pid) {
|
|
@@ -285,6 +296,7 @@ export class KeyedJournal {
|
|
|
285
296
|
sentHashes: [],
|
|
286
297
|
unknown: false,
|
|
287
298
|
legacy,
|
|
299
|
+
objection: objectionOf(e.objection),
|
|
288
300
|
});
|
|
289
301
|
return;
|
|
290
302
|
}
|
|
@@ -382,9 +394,9 @@ export class KeyedJournal {
|
|
|
382
394
|
}
|
|
383
395
|
return v;
|
|
384
396
|
}
|
|
385
|
-
reserve(action, escrowId, amountWei, nowSec) {
|
|
397
|
+
reserve(action, escrowId, amountWei, nowSec, objection) {
|
|
386
398
|
const id = randomUUID();
|
|
387
|
-
this.append({ t: "reserve", id, action, escrowId, amountWei: amountWei.toString(), at: nowSec }, nowSec);
|
|
399
|
+
this.append({ t: "reserve", id, action, escrowId, amountWei: amountWei.toString(), at: nowSec, ...(objection ? { objection } : {}) }, nowSec);
|
|
388
400
|
return id;
|
|
389
401
|
}
|
|
390
402
|
signed(id, hash, nonce, tx) {
|
package/dist/reason.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** 32 fresh random bytes (ethers' randomBytes: node:crypto on Node), lowercase 0x hex. */
|
|
2
|
+
export declare function newReasonSalt(): string;
|
|
3
|
+
/** keccak256(salt ‖ utf8(reason)), lowercase. */
|
|
4
|
+
export declare function objectionReasonHash(reason: string, salt: string): string;
|
package/dist/reason.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The objection's reasonHash — keccak256(salt ‖ utf8(reason)), with a salt of 32
|
|
3
|
+
* random bytes made HERE, on the payer's machine, and never sent to cascrow.
|
|
4
|
+
*
|
|
5
|
+
* The hash goes on two public ledgers for good (the `Objected` event; cascrow's
|
|
6
|
+
* CLAIM_OBJECTED audit memo on the XRP Ledger). 0.2.0 sent keccak256(utf8(reason)),
|
|
7
|
+
* which anyone can test guessed reasons against; with the salt only its holder can
|
|
8
|
+
* link a text to the hash. The salt is returned in the action's result and written
|
|
9
|
+
* to the local journal, next to the reason — keep it, it is the only way to show
|
|
10
|
+
* later which reason the hash commits to.
|
|
11
|
+
*
|
|
12
|
+
* A port of cascrow's src/lib/v3-reason-hash.ts (this package cannot import the
|
|
13
|
+
* app). The same fixed vector is asserted against both
|
|
14
|
+
* (src/__tests__/helpers/reason-hash-vector.ts).
|
|
15
|
+
*/
|
|
16
|
+
import { concat, getBytes, hexlify, keccak256, randomBytes, toUtf8Bytes } from "ethers";
|
|
17
|
+
const SALT = /^0x[0-9a-f]{64}$/;
|
|
18
|
+
/** 32 fresh random bytes (ethers' randomBytes: node:crypto on Node), lowercase 0x hex. */
|
|
19
|
+
export function newReasonSalt() {
|
|
20
|
+
return hexlify(randomBytes(32)).toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
/** keccak256(salt ‖ utf8(reason)), lowercase. */
|
|
23
|
+
export function objectionReasonHash(reason, salt) {
|
|
24
|
+
if (!SALT.test(salt))
|
|
25
|
+
throw new Error("reason salt must be 0x + 64 lowercase hex characters (32 bytes)");
|
|
26
|
+
return keccak256(concat([getBytes(salt), toUtf8Bytes(reason)])).toLowerCase();
|
|
27
|
+
}
|
package/dist/remote.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class Remote {
|
|
|
14
14
|
constructor(cfg: RemoteConfig);
|
|
15
15
|
get configured(): boolean;
|
|
16
16
|
private call;
|
|
17
|
+
/** `reasonHash` is the salted keccak256(salt ‖ utf8(reason)) made in reason.ts; the reason and the salt are never sent. */
|
|
17
18
|
prepare(q: {
|
|
18
19
|
milestoneId: string;
|
|
19
20
|
action: string;
|
package/dist/remote.js
CHANGED
|
@@ -75,6 +75,7 @@ export class Remote {
|
|
|
75
75
|
}
|
|
76
76
|
return data;
|
|
77
77
|
}
|
|
78
|
+
/** `reasonHash` is the salted keccak256(salt ‖ utf8(reason)) made in reason.ts; the reason and the salt are never sent. */
|
|
78
79
|
prepare(q) {
|
|
79
80
|
const p = new URLSearchParams();
|
|
80
81
|
for (const [k, v] of Object.entries(q))
|
package/dist/tools.js
CHANGED
|
@@ -66,7 +66,7 @@ export const SIGNER_TOOLS = Object.freeze([
|
|
|
66
66
|
name: "cascrow_signer_object",
|
|
67
67
|
description: "As the PAYER, object to the live claim before its objection deadline — this stops the release. Only for escrows whose on-chain payer is this key " +
|
|
68
68
|
"(read from the chain; the local book is not needed). cascrow's server is not needed; the transaction is built from the chain. If the objection is pending too long, use cascrow_signer_speed_up.",
|
|
69
|
-
inputSchema: { type: "object", required: ["reason"], properties: { ...escrowRef, reason: { type: "string", description: "Why
|
|
69
|
+
inputSchema: { type: "object", required: ["reason"], properties: { ...escrowRef, reason: { type: "string", description: "Why. Only keccak256(salt ‖ utf8(reason)) goes on chain, with a salt of 32 random bytes made on this machine; the result returns reasonSalt (also kept in the local journal) — keep it with the reason, without it the hash proves nothing. Neither the reason nor the salt is sent to cascrow." } } },
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
name: "cascrow_signer_release",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cascrow-signer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Local signer for cascrow MilestoneEscrowV3 escrows — your key is generated, encrypted and used only on your machine; cascrow prepares, you check and sign",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/api.js",
|