@calimero-network/mero-js 22.4.0 → 22.5.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/README.md +4 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +317 -25
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +317 -25
- package/dist/index.mjs.map +4 -4
- package/dist/namespace-op/namespace-op.d.ts +8 -4
- package/dist/namespace-op/namespace-op.js +8 -4
- package/dist/relay/index.d.ts +1 -1
- package/dist/relay/relay-client.d.ts +56 -0
- package/dist/relay/relay-client.js +62 -7
- package/dist/warrant/governance-op.d.ts +81 -0
- package/dist/warrant/governance-op.js +125 -0
- package/dist/warrant/governance-warrant.d.ts +106 -0
- package/dist/warrant/governance-warrant.js +159 -0
- package/dist/warrant/index.d.ts +4 -0
- package/dist/warrant/index.js +2 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -18,14 +18,14 @@ export type { Codec, EphemeralEntry } from "./ephemeral/index.js";
|
|
|
18
18
|
export * from "./cloud/index.js";
|
|
19
19
|
export * from "./sealed/index.js";
|
|
20
20
|
export * from "./relay/index.js";
|
|
21
|
-
export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, } from "./warrant/index.js";
|
|
21
|
+
export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, signGovernanceWarrant, parseGovernanceWarrant, governanceOpHash, memberAddedOp, memberRemovedOp, memberLeftOp, memberRoleSetOp, groupCreatedOp, groupReparentedOp, groupDeletedOp, } from "./warrant/index.js";
|
|
22
22
|
export { generateAccountRoot, accountRootFromPhrase, accountRootFromSecret, signAccountLink, signAccountLogin, } from "./account/index.js";
|
|
23
23
|
export type { AccountRoot, RecoverableAccountRoot, AccountLinkInput, AccountLoginInput, } from "./account/index.js";
|
|
24
24
|
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, } from "./device-cert/index.js";
|
|
25
25
|
export type { DeviceCertInput } from "./device-cert/index.js";
|
|
26
26
|
export { signMemberJoinOp, encodeSignedInvitation, SIGNED_NAMESPACE_OP_SCHEMA_VERSION, } from "./namespace-op/index.js";
|
|
27
27
|
export type { SignMemberJoinInput } from "./namespace-op/index.js";
|
|
28
|
-
export type { WarrantInput, CreationWarrantInput, CreationWarrantFields, SignedCreationWarrant, } from "./warrant/index.js";
|
|
28
|
+
export type { WarrantInput, CreationWarrantInput, CreationWarrantFields, SignedCreationWarrant, GovernanceWarrantInput, GovernanceWarrantFields, GovernanceOp, GovernanceOpKind, GovernanceMemberRole, GroupCreatedInput, } from "./warrant/index.js";
|
|
29
29
|
export { requestBodyHash, signRequest, callerProof, createProofSigner, } from "./request/index.js";
|
|
30
30
|
export type { CallerProofInput, ProofRequest, ProofSignerOptions, } from "./request/index.js";
|
|
31
31
|
export type { RequestSigInput } from "./request/index.js";
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ export * from "./sealed/index.js";
|
|
|
27
27
|
// Relay client — write through delegated execution, holding only a signing key
|
|
28
28
|
export * from "./relay/index.js";
|
|
29
29
|
// Warrant signing — mint the author's consent for a relay to run one intent
|
|
30
|
-
export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, } from "./warrant/index.js";
|
|
30
|
+
export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, signGovernanceWarrant, parseGovernanceWarrant, governanceOpHash, memberAddedOp, memberRemovedOp, memberLeftOp, memberRoleSetOp, groupCreatedOp, groupReparentedOp, groupDeletedOp, } from "./warrant/index.js";
|
|
31
31
|
// Account roots — mint one with a recovery phrase, or prove you hold one
|
|
32
32
|
export { generateAccountRoot, accountRootFromPhrase, accountRootFromSecret, signAccountLink, signAccountLogin, } from "./account/index.js";
|
|
33
33
|
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, } from "./device-cert/index.js";
|
package/dist/index.mjs
CHANGED
|
@@ -6627,9 +6627,9 @@ function parseCreationWarrant(warrant) {
|
|
|
6627
6627
|
const u32 = (what) => view.getUint32(take(4, what).byteOffset, true);
|
|
6628
6628
|
const u64 = (what) => view.getBigUint64(take(8, what).byteOffset, true);
|
|
6629
6629
|
const option = (what) => {
|
|
6630
|
-
const
|
|
6631
|
-
if (
|
|
6632
|
-
if (
|
|
6630
|
+
const tag2 = take(1, what)[0];
|
|
6631
|
+
if (tag2 === 0) return null;
|
|
6632
|
+
if (tag2 !== 1) throw new Error(`${what} has option tag ${tag2}, expected 0 or 1`);
|
|
6633
6633
|
const len = u32(what);
|
|
6634
6634
|
if (len > MAX_LABEL_BYTES) {
|
|
6635
6635
|
throw new Error(`${what} is ${len} bytes, over the ${MAX_LABEL_BYTES} a node accepts`);
|
|
@@ -6681,6 +6681,134 @@ function borshOption(bytes) {
|
|
|
6681
6681
|
return concat(new Uint8Array([1]), u32le(bytes.length), bytes);
|
|
6682
6682
|
}
|
|
6683
6683
|
|
|
6684
|
+
// src/warrant/governance-warrant.ts
|
|
6685
|
+
var SIGN_DOMAIN4 = new TextEncoder().encode("calimero.governance-warrant.v1");
|
|
6686
|
+
var OP_DOMAIN = new TextEncoder().encode("calimero.governance-warrant.op.v1");
|
|
6687
|
+
var KIND_BYTE = { group: 0, root: 1 };
|
|
6688
|
+
async function governanceOpHash(op) {
|
|
6689
|
+
return domainHash(OP_DOMAIN, [new Uint8Array([kindByte(op.kind)]), op.bytes]);
|
|
6690
|
+
}
|
|
6691
|
+
async function governanceWarrantPreimage(p) {
|
|
6692
|
+
return domainHash(SIGN_DOMAIN4, [
|
|
6693
|
+
p.scope,
|
|
6694
|
+
new Uint8Array([kindByte(p.kind)]),
|
|
6695
|
+
p.authorAccount,
|
|
6696
|
+
p.deviceKey,
|
|
6697
|
+
p.executor,
|
|
6698
|
+
p.opHash,
|
|
6699
|
+
u64le(p.accountHeads.length),
|
|
6700
|
+
...p.accountHeads,
|
|
6701
|
+
u64le(p.governanceFloor.length),
|
|
6702
|
+
...p.governanceFloor,
|
|
6703
|
+
u64le(p.nonce),
|
|
6704
|
+
u64le(p.notAfter)
|
|
6705
|
+
]);
|
|
6706
|
+
}
|
|
6707
|
+
async function signGovernanceWarrant(input) {
|
|
6708
|
+
const scope = fromHex(input.scope, "scope", 32);
|
|
6709
|
+
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
6710
|
+
const executor = fromHex(input.executor, "executor", 32);
|
|
6711
|
+
const accountHeads = citedHeads(input.accountHeads, "accountHeads");
|
|
6712
|
+
const governanceFloor = citedHeads(input.governanceFloor, "governanceFloor");
|
|
6713
|
+
const kind = kindByte(input.op.kind);
|
|
6714
|
+
const key = await importSigningKey(input.deviceSecret);
|
|
6715
|
+
const deviceKey = await derivePublicKey(input.deviceSecret);
|
|
6716
|
+
const opHash = await governanceOpHash(input.op);
|
|
6717
|
+
const preimage = await governanceWarrantPreimage({
|
|
6718
|
+
scope,
|
|
6719
|
+
kind: input.op.kind,
|
|
6720
|
+
authorAccount,
|
|
6721
|
+
deviceKey,
|
|
6722
|
+
executor,
|
|
6723
|
+
opHash,
|
|
6724
|
+
accountHeads,
|
|
6725
|
+
governanceFloor,
|
|
6726
|
+
nonce: input.nonce,
|
|
6727
|
+
notAfter: input.notAfter
|
|
6728
|
+
});
|
|
6729
|
+
const signature = new Uint8Array(
|
|
6730
|
+
await crypto.subtle.sign({ name: "Ed25519" }, key, preimage)
|
|
6731
|
+
);
|
|
6732
|
+
return hex(
|
|
6733
|
+
concat(
|
|
6734
|
+
scope,
|
|
6735
|
+
new Uint8Array([kind]),
|
|
6736
|
+
authorAccount,
|
|
6737
|
+
deviceKey,
|
|
6738
|
+
executor,
|
|
6739
|
+
opHash,
|
|
6740
|
+
u32le(accountHeads.length),
|
|
6741
|
+
...accountHeads,
|
|
6742
|
+
u32le(governanceFloor.length),
|
|
6743
|
+
...governanceFloor,
|
|
6744
|
+
u64le(input.nonce),
|
|
6745
|
+
u64le(input.notAfter),
|
|
6746
|
+
signature
|
|
6747
|
+
)
|
|
6748
|
+
);
|
|
6749
|
+
}
|
|
6750
|
+
function parseGovernanceWarrant(warrant) {
|
|
6751
|
+
const clean = warrant.trim();
|
|
6752
|
+
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length % 2 !== 0) {
|
|
6753
|
+
throw new Error("governance warrant must be an even number of hex characters");
|
|
6754
|
+
}
|
|
6755
|
+
const bytes = new Uint8Array(clean.length / 2);
|
|
6756
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
6757
|
+
bytes[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
6758
|
+
}
|
|
6759
|
+
const view = new DataView(bytes.buffer);
|
|
6760
|
+
let o = 0;
|
|
6761
|
+
const take = (n, what) => {
|
|
6762
|
+
if (o + n > bytes.length) {
|
|
6763
|
+
throw new Error(`governance warrant ends inside ${what} (${bytes.length} bytes)`);
|
|
6764
|
+
}
|
|
6765
|
+
const out = bytes.subarray(o, o + n);
|
|
6766
|
+
o += n;
|
|
6767
|
+
return out;
|
|
6768
|
+
};
|
|
6769
|
+
const u32 = (what) => view.getUint32(take(4, what).byteOffset, true);
|
|
6770
|
+
const u64 = (what) => view.getBigUint64(take(8, what).byteOffset, true);
|
|
6771
|
+
const heads = (what) => {
|
|
6772
|
+
const count = u32(what);
|
|
6773
|
+
if (count > 64) {
|
|
6774
|
+
throw new Error(`${what} cites ${count} heads, over the 64 a node accepts`);
|
|
6775
|
+
}
|
|
6776
|
+
return Array.from({ length: count }, () => hex(take(32, what)));
|
|
6777
|
+
};
|
|
6778
|
+
const kind = () => {
|
|
6779
|
+
const byte = take(1, "kind")[0];
|
|
6780
|
+
if (byte === 0) return "group";
|
|
6781
|
+
if (byte === 1) return "root";
|
|
6782
|
+
throw new Error(`governance warrant has kind ${byte}, expected 0 (group) or 1 (root)`);
|
|
6783
|
+
};
|
|
6784
|
+
const fields = {
|
|
6785
|
+
scope: hex(take(32, "scope")),
|
|
6786
|
+
kind: kind(),
|
|
6787
|
+
authorAccount: hex(take(32, "authorAccount")),
|
|
6788
|
+
deviceKey: hex(take(32, "deviceKey")),
|
|
6789
|
+
executor: hex(take(32, "executor")),
|
|
6790
|
+
opHash: hex(take(32, "opHash")),
|
|
6791
|
+
accountHeads: heads("accountHeads"),
|
|
6792
|
+
governanceFloor: heads("governanceFloor"),
|
|
6793
|
+
nonce: u64("nonce"),
|
|
6794
|
+
notAfter: u64("notAfter"),
|
|
6795
|
+
signature: hex(take(64, "signature"))
|
|
6796
|
+
};
|
|
6797
|
+
if (o !== bytes.length) {
|
|
6798
|
+
throw new Error(
|
|
6799
|
+
`governance warrant is ${bytes.length} bytes but its fields account for ${o}`
|
|
6800
|
+
);
|
|
6801
|
+
}
|
|
6802
|
+
return fields;
|
|
6803
|
+
}
|
|
6804
|
+
function kindByte(kind) {
|
|
6805
|
+
const byte = KIND_BYTE[kind];
|
|
6806
|
+
if (byte === void 0) {
|
|
6807
|
+
throw new Error(`op kind must be 'group' or 'root', got ${String(kind)}`);
|
|
6808
|
+
}
|
|
6809
|
+
return byte;
|
|
6810
|
+
}
|
|
6811
|
+
|
|
6684
6812
|
// src/relay/relay-client.ts
|
|
6685
6813
|
var DEFAULT_TTL_SECONDS = 300;
|
|
6686
6814
|
var IntentRefusedError = class extends Error {
|
|
@@ -6794,14 +6922,7 @@ var RelayClient = class {
|
|
|
6794
6922
|
403
|
|
6795
6923
|
);
|
|
6796
6924
|
}
|
|
6797
|
-
const
|
|
6798
|
-
if (configured && configured.toLowerCase() !== described.executorAccount.toLowerCase()) {
|
|
6799
|
-
throw new Error(
|
|
6800
|
-
`configured executorAccount ${configured} is not the relay's account ${described.executorAccount}; a warrant naming it would be unspendable`
|
|
6801
|
-
);
|
|
6802
|
-
}
|
|
6803
|
-
const executor = described.executorAccount;
|
|
6804
|
-
this.executorAccount = executor;
|
|
6925
|
+
const executor = this.checkedExecutor(described.executorAccount);
|
|
6805
6926
|
const initArgs = input.initArgs ?? {};
|
|
6806
6927
|
const nonce2 = await this.config.nonces.next();
|
|
6807
6928
|
const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
@@ -6829,6 +6950,75 @@ var RelayClient = class {
|
|
|
6829
6950
|
memberPublicKey: body.data.memberPublicKey
|
|
6830
6951
|
};
|
|
6831
6952
|
}
|
|
6953
|
+
/**
|
|
6954
|
+
* Ask the relay whether it may publish governance ops for members of
|
|
6955
|
+
* `groupId`, and which account a warrant must name.
|
|
6956
|
+
*/
|
|
6957
|
+
async describeGovernance(groupId) {
|
|
6958
|
+
const body = await this.json(
|
|
6959
|
+
"GET",
|
|
6960
|
+
`/admin-api/groups/${encodeURIComponent(groupId)}/governance-intents`
|
|
6961
|
+
);
|
|
6962
|
+
return body.data;
|
|
6963
|
+
}
|
|
6964
|
+
/**
|
|
6965
|
+
* Publish one governance op through the relay, as the author.
|
|
6966
|
+
*
|
|
6967
|
+
* The warrant commits to the op's exact bytes and is scoped to `groupId`, so
|
|
6968
|
+
* the relay can neither change what the op does nor spend it elsewhere. Every
|
|
6969
|
+
* peer applies the op as the author, so the author's own rights decide
|
|
6970
|
+
* (`MANAGE_MEMBERS` to add a member, `CAN_CREATE_SUBGROUP` to create a
|
|
6971
|
+
* subgroup, and so on); a lack of them comes back as an
|
|
6972
|
+
* {@link IntentRefusedError} from the relay.
|
|
6973
|
+
*
|
|
6974
|
+
* Always asks {@link describeGovernance} first and refuses *before* taking a
|
|
6975
|
+
* nonce when the relay has no standing, for the reason `createContext` does.
|
|
6976
|
+
* The nonce comes from the configured {@link NonceSource}; it is spent in a
|
|
6977
|
+
* per-group ledger, and a monotonic source is correct for it as for every
|
|
6978
|
+
* other warrant.
|
|
6979
|
+
*/
|
|
6980
|
+
async govern(input) {
|
|
6981
|
+
const described = await this.describeGovernance(input.groupId);
|
|
6982
|
+
if (!described.canActOnBehalf) {
|
|
6983
|
+
throw new IntentRefusedError(
|
|
6984
|
+
`the relay (${described.executorAccount}) has no standing to act for members of group ${described.groupId}; an admin must admit it as a relay or grant it CAN_AUTHOR_ON_BEHALF (checked before signing, no nonce was spent)`,
|
|
6985
|
+
false,
|
|
6986
|
+
403
|
|
6987
|
+
);
|
|
6988
|
+
}
|
|
6989
|
+
const executor = this.checkedExecutor(described.executorAccount);
|
|
6990
|
+
const nonce2 = await this.config.nonces.next();
|
|
6991
|
+
const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
6992
|
+
const warrant = await signGovernanceWarrant({
|
|
6993
|
+
scope: input.groupId,
|
|
6994
|
+
op: input.op,
|
|
6995
|
+
authorAccount: this.config.authorAccount,
|
|
6996
|
+
executor,
|
|
6997
|
+
nonce: nonce2,
|
|
6998
|
+
notAfter: BigInt(Math.floor(Date.now() / 1e3)) + BigInt(ttl),
|
|
6999
|
+
deviceSecret: this.config.deviceSecret
|
|
7000
|
+
});
|
|
7001
|
+
const body = await this.json(
|
|
7002
|
+
"POST",
|
|
7003
|
+
`/admin-api/groups/${encodeURIComponent(input.groupId)}/governance-intents`,
|
|
7004
|
+
{ warrant, authorProof: this.config.authorProof, op: hex(input.op.bytes) }
|
|
7005
|
+
);
|
|
7006
|
+
return { groupId: body.data.groupId };
|
|
7007
|
+
}
|
|
7008
|
+
/**
|
|
7009
|
+
* The executor a warrant must name: the one the relay answered with, which a
|
|
7010
|
+
* configured account must agree with. Remembered for later calls.
|
|
7011
|
+
*/
|
|
7012
|
+
checkedExecutor(answered) {
|
|
7013
|
+
const configured = this.config.executorAccount;
|
|
7014
|
+
if (configured && configured.toLowerCase() !== answered.toLowerCase()) {
|
|
7015
|
+
throw new Error(
|
|
7016
|
+
`configured executorAccount ${configured} is not the relay's account ${answered}; a warrant naming it would be unspendable`
|
|
7017
|
+
);
|
|
7018
|
+
}
|
|
7019
|
+
this.executorAccount = answered;
|
|
7020
|
+
return answered;
|
|
7021
|
+
}
|
|
6832
7022
|
async json(method, path, body) {
|
|
6833
7023
|
const headers = { Accept: "application/json" };
|
|
6834
7024
|
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
@@ -7715,8 +7905,8 @@ var SIGNATURE_HASHES = {
|
|
|
7715
7905
|
};
|
|
7716
7906
|
function read(bytes, offset, limit) {
|
|
7717
7907
|
if (offset + 2 > limit) throw new Error("it is truncated");
|
|
7718
|
-
const
|
|
7719
|
-
if ((
|
|
7908
|
+
const tag2 = bytes[offset];
|
|
7909
|
+
if ((tag2 & 31) === 31) throw new Error("it uses a tag this parser does not read");
|
|
7720
7910
|
let length = bytes[offset + 1];
|
|
7721
7911
|
let start = offset + 2;
|
|
7722
7912
|
if (length & 128) {
|
|
@@ -7728,7 +7918,7 @@ function read(bytes, offset, limit) {
|
|
|
7728
7918
|
}
|
|
7729
7919
|
const end = start + length;
|
|
7730
7920
|
if (end > limit) throw new Error("it is truncated");
|
|
7731
|
-
return { tag, bytes, offset, start, end };
|
|
7921
|
+
return { tag: tag2, bytes, offset, start, end };
|
|
7732
7922
|
}
|
|
7733
7923
|
function parseDer(bytes) {
|
|
7734
7924
|
const element = read(bytes, 0, bytes.length);
|
|
@@ -7744,8 +7934,8 @@ function children(element) {
|
|
|
7744
7934
|
}
|
|
7745
7935
|
return out;
|
|
7746
7936
|
}
|
|
7747
|
-
function expectTag(element,
|
|
7748
|
-
if (!element || element.tag !==
|
|
7937
|
+
function expectTag(element, tag2, what) {
|
|
7938
|
+
if (!element || element.tag !== tag2) throw new Error(`${what} is not where it should be`);
|
|
7749
7939
|
return element;
|
|
7750
7940
|
}
|
|
7751
7941
|
function contents(element) {
|
|
@@ -8207,11 +8397,103 @@ function splitVersion2(version) {
|
|
|
8207
8397
|
return [[Number(match[1]), Number(match[2]), Number(match[3])], match[4]];
|
|
8208
8398
|
}
|
|
8209
8399
|
|
|
8400
|
+
// src/warrant/governance-op.ts
|
|
8401
|
+
var ROLE = {
|
|
8402
|
+
Admin: 0,
|
|
8403
|
+
Member: 1,
|
|
8404
|
+
ReadOnly: 2
|
|
8405
|
+
};
|
|
8406
|
+
var GROUP_OP = {
|
|
8407
|
+
MemberAdded: 1,
|
|
8408
|
+
MemberRemoved: 2,
|
|
8409
|
+
MemberLeft: 3,
|
|
8410
|
+
MemberRoleSet: 4
|
|
8411
|
+
};
|
|
8412
|
+
var ROOT_OP = {
|
|
8413
|
+
GroupCreated: 0,
|
|
8414
|
+
GroupReparented: 1,
|
|
8415
|
+
GroupDeleted: 2
|
|
8416
|
+
};
|
|
8417
|
+
var CLEARED_HASH = new Uint8Array(32);
|
|
8418
|
+
var EMPTY_VEC = u32le(0);
|
|
8419
|
+
function role(value) {
|
|
8420
|
+
const byte = ROLE[value];
|
|
8421
|
+
if (byte === void 0) {
|
|
8422
|
+
throw new Error(`role must be Admin, Member or ReadOnly, got ${String(value)}`);
|
|
8423
|
+
}
|
|
8424
|
+
return new Uint8Array([byte]);
|
|
8425
|
+
}
|
|
8426
|
+
function tag(byte) {
|
|
8427
|
+
return new Uint8Array([byte]);
|
|
8428
|
+
}
|
|
8429
|
+
function memberAddedOp(member, memberRole) {
|
|
8430
|
+
return {
|
|
8431
|
+
kind: "group",
|
|
8432
|
+
bytes: concat(tag(GROUP_OP.MemberAdded), fromHex(member, "member", 32), role(memberRole))
|
|
8433
|
+
};
|
|
8434
|
+
}
|
|
8435
|
+
function memberRemovedOp(member) {
|
|
8436
|
+
return {
|
|
8437
|
+
kind: "group",
|
|
8438
|
+
bytes: concat(
|
|
8439
|
+
tag(GROUP_OP.MemberRemoved),
|
|
8440
|
+
fromHex(member, "member", 32),
|
|
8441
|
+
CLEARED_HASH,
|
|
8442
|
+
EMPTY_VEC
|
|
8443
|
+
)
|
|
8444
|
+
};
|
|
8445
|
+
}
|
|
8446
|
+
function memberLeftOp(member) {
|
|
8447
|
+
return {
|
|
8448
|
+
kind: "group",
|
|
8449
|
+
bytes: concat(
|
|
8450
|
+
tag(GROUP_OP.MemberLeft),
|
|
8451
|
+
fromHex(member, "member", 32),
|
|
8452
|
+
CLEARED_HASH,
|
|
8453
|
+
EMPTY_VEC
|
|
8454
|
+
)
|
|
8455
|
+
};
|
|
8456
|
+
}
|
|
8457
|
+
function memberRoleSetOp(member, memberRole) {
|
|
8458
|
+
return {
|
|
8459
|
+
kind: "group",
|
|
8460
|
+
bytes: concat(tag(GROUP_OP.MemberRoleSet), fromHex(member, "member", 32), role(memberRole))
|
|
8461
|
+
};
|
|
8462
|
+
}
|
|
8463
|
+
function groupCreatedOp(input) {
|
|
8464
|
+
return {
|
|
8465
|
+
kind: "root",
|
|
8466
|
+
bytes: concat(
|
|
8467
|
+
tag(ROOT_OP.GroupCreated),
|
|
8468
|
+
fromHex(input.groupId, "groupId", 32),
|
|
8469
|
+
fromHex(input.parentId, "parentId", 32),
|
|
8470
|
+
tag(input.restricted ? 1 : 0),
|
|
8471
|
+
fromHex(input.admin, "admin", 32)
|
|
8472
|
+
)
|
|
8473
|
+
};
|
|
8474
|
+
}
|
|
8475
|
+
function groupReparentedOp(childGroupId, newParentId) {
|
|
8476
|
+
return {
|
|
8477
|
+
kind: "root",
|
|
8478
|
+
bytes: concat(
|
|
8479
|
+
tag(ROOT_OP.GroupReparented),
|
|
8480
|
+
fromHex(childGroupId, "childGroupId", 32),
|
|
8481
|
+
fromHex(newParentId, "newParentId", 32)
|
|
8482
|
+
)
|
|
8483
|
+
};
|
|
8484
|
+
}
|
|
8485
|
+
function groupDeletedOp(rootGroupId) {
|
|
8486
|
+
return {
|
|
8487
|
+
kind: "root",
|
|
8488
|
+
bytes: concat(tag(ROOT_OP.GroupDeleted), fromHex(rootGroupId, "rootGroupId", 32), EMPTY_VEC, EMPTY_VEC)
|
|
8489
|
+
};
|
|
8490
|
+
}
|
|
8491
|
+
|
|
8210
8492
|
// src/namespace-op/namespace-op.ts
|
|
8211
|
-
var SIGNED_NAMESPACE_OP_SCHEMA_VERSION =
|
|
8493
|
+
var SIGNED_NAMESPACE_OP_SCHEMA_VERSION = 15;
|
|
8212
8494
|
var NAMESPACE_SIGN_DOMAIN = new TextEncoder().encode("calimero.namespace.v1");
|
|
8213
8495
|
var NAMESPACE_OP_ROOT = 0;
|
|
8214
|
-
var
|
|
8496
|
+
var ROOT_OP2 = {
|
|
8215
8497
|
GroupCreated: 0,
|
|
8216
8498
|
GroupReparented: 1,
|
|
8217
8499
|
GroupDeleted: 2,
|
|
@@ -8286,13 +8568,13 @@ async function signMemberJoinOp(input) {
|
|
|
8286
8568
|
const expires = BigInt(input.invitation.invitation.expiration_timestamp ?? 0) !== 0n;
|
|
8287
8569
|
const joinedAt = input.joinedAt ?? BigInt(Math.floor(Date.now() / 1e3));
|
|
8288
8570
|
const rootOp = expires ? concat(
|
|
8289
|
-
new Uint8Array([
|
|
8571
|
+
new Uint8Array([ROOT_OP2.MemberJoinedAt]),
|
|
8290
8572
|
fromHex(input.member, "member", 32),
|
|
8291
8573
|
encodeSignedInvitation(input.invitation),
|
|
8292
8574
|
u64le(joinedAt),
|
|
8293
8575
|
credential
|
|
8294
8576
|
) : concat(
|
|
8295
|
-
new Uint8Array([
|
|
8577
|
+
new Uint8Array([ROOT_OP2.MemberJoined]),
|
|
8296
8578
|
fromHex(input.member, "member", 32),
|
|
8297
8579
|
encodeSignedInvitation(input.invitation),
|
|
8298
8580
|
credential
|
|
@@ -8317,7 +8599,7 @@ async function signMemberJoinOp(input) {
|
|
|
8317
8599
|
}
|
|
8318
8600
|
|
|
8319
8601
|
// src/login/login.ts
|
|
8320
|
-
var
|
|
8602
|
+
var SIGN_DOMAIN5 = new TextEncoder().encode("calimero.auth.login.v1");
|
|
8321
8603
|
var AUDIENCE_TAG = {
|
|
8322
8604
|
webOrigin: 0,
|
|
8323
8605
|
codeSigningId: 1,
|
|
@@ -8341,12 +8623,12 @@ function audienceSigningBytes(audience) {
|
|
|
8341
8623
|
);
|
|
8342
8624
|
}
|
|
8343
8625
|
function audienceWire(audience) {
|
|
8344
|
-
const
|
|
8626
|
+
const tag2 = Uint8Array.from([AUDIENCE_TAG[audience.kind]]);
|
|
8345
8627
|
if (audience.kind === "cli") {
|
|
8346
|
-
return
|
|
8628
|
+
return tag2;
|
|
8347
8629
|
}
|
|
8348
8630
|
const body = audienceBody(audience);
|
|
8349
|
-
return concat(
|
|
8631
|
+
return concat(tag2, u32le(body.length), body);
|
|
8350
8632
|
}
|
|
8351
8633
|
async function signLoginStatement(input) {
|
|
8352
8634
|
const node = fromHex(input.node, "node", 32);
|
|
@@ -8356,7 +8638,7 @@ async function signLoginStatement(input) {
|
|
|
8356
8638
|
const deviceKey = await derivePublicKey(input.deviceSecret);
|
|
8357
8639
|
const issuedAt = u64le(input.issuedAt);
|
|
8358
8640
|
const expiresAt = u64le(input.expiresAt);
|
|
8359
|
-
const preimage = await domainHash(
|
|
8641
|
+
const preimage = await domainHash(SIGN_DOMAIN5, [
|
|
8360
8642
|
node,
|
|
8361
8643
|
audienceSigningBytes(input.audience),
|
|
8362
8644
|
challenge,
|
|
@@ -8600,6 +8882,10 @@ export {
|
|
|
8600
8882
|
fetchNodeReleaseVersion,
|
|
8601
8883
|
generateAccountRoot,
|
|
8602
8884
|
generateSessionKey,
|
|
8885
|
+
governanceOpHash,
|
|
8886
|
+
groupCreatedOp,
|
|
8887
|
+
groupDeletedOp,
|
|
8888
|
+
groupReparentedOp,
|
|
8603
8889
|
hasCap,
|
|
8604
8890
|
hexEncodeUtf8,
|
|
8605
8891
|
intentHash,
|
|
@@ -8607,11 +8893,16 @@ export {
|
|
|
8607
8893
|
jsonCodec,
|
|
8608
8894
|
localNodeUrl,
|
|
8609
8895
|
login,
|
|
8896
|
+
memberAddedOp,
|
|
8897
|
+
memberLeftOp,
|
|
8898
|
+
memberRemovedOp,
|
|
8899
|
+
memberRoleSetOp,
|
|
8610
8900
|
mintDeviceId,
|
|
8611
8901
|
nodeEndpoint,
|
|
8612
8902
|
nodeReleaseVersionFromImage,
|
|
8613
8903
|
parseAuthCallback,
|
|
8614
8904
|
parseCreationWarrant,
|
|
8905
|
+
parseGovernanceWarrant,
|
|
8615
8906
|
probeNodeHealth,
|
|
8616
8907
|
redeemInvitation,
|
|
8617
8908
|
requestBodyHash,
|
|
@@ -8621,6 +8912,7 @@ export {
|
|
|
8621
8912
|
signAccountLogin,
|
|
8622
8913
|
signCreationWarrant,
|
|
8623
8914
|
signDeviceCert,
|
|
8915
|
+
signGovernanceWarrant,
|
|
8624
8916
|
signLoginStatement,
|
|
8625
8917
|
signMemberJoinOp,
|
|
8626
8918
|
signRequest,
|