@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.cjs
CHANGED
|
@@ -88,6 +88,10 @@ __export(index_exports, {
|
|
|
88
88
|
fetchNodeReleaseVersion: () => fetchNodeReleaseVersion,
|
|
89
89
|
generateAccountRoot: () => generateAccountRoot,
|
|
90
90
|
generateSessionKey: () => generateSessionKey,
|
|
91
|
+
governanceOpHash: () => governanceOpHash,
|
|
92
|
+
groupCreatedOp: () => groupCreatedOp,
|
|
93
|
+
groupDeletedOp: () => groupDeletedOp,
|
|
94
|
+
groupReparentedOp: () => groupReparentedOp,
|
|
91
95
|
hasCap: () => hasCap,
|
|
92
96
|
hexEncodeUtf8: () => hexEncodeUtf8,
|
|
93
97
|
intentHash: () => intentHash,
|
|
@@ -95,11 +99,16 @@ __export(index_exports, {
|
|
|
95
99
|
jsonCodec: () => jsonCodec,
|
|
96
100
|
localNodeUrl: () => localNodeUrl,
|
|
97
101
|
login: () => login,
|
|
102
|
+
memberAddedOp: () => memberAddedOp,
|
|
103
|
+
memberLeftOp: () => memberLeftOp,
|
|
104
|
+
memberRemovedOp: () => memberRemovedOp,
|
|
105
|
+
memberRoleSetOp: () => memberRoleSetOp,
|
|
98
106
|
mintDeviceId: () => mintDeviceId,
|
|
99
107
|
nodeEndpoint: () => nodeEndpoint,
|
|
100
108
|
nodeReleaseVersionFromImage: () => nodeReleaseVersionFromImage,
|
|
101
109
|
parseAuthCallback: () => parseAuthCallback,
|
|
102
110
|
parseCreationWarrant: () => parseCreationWarrant,
|
|
111
|
+
parseGovernanceWarrant: () => parseGovernanceWarrant,
|
|
103
112
|
probeNodeHealth: () => probeNodeHealth,
|
|
104
113
|
redeemInvitation: () => redeemInvitation,
|
|
105
114
|
requestBodyHash: () => requestBodyHash,
|
|
@@ -109,6 +118,7 @@ __export(index_exports, {
|
|
|
109
118
|
signAccountLogin: () => signAccountLogin,
|
|
110
119
|
signCreationWarrant: () => signCreationWarrant,
|
|
111
120
|
signDeviceCert: () => signDeviceCert,
|
|
121
|
+
signGovernanceWarrant: () => signGovernanceWarrant,
|
|
112
122
|
signLoginStatement: () => signLoginStatement,
|
|
113
123
|
signMemberJoinOp: () => signMemberJoinOp,
|
|
114
124
|
signRequest: () => signRequest,
|
|
@@ -6753,9 +6763,9 @@ function parseCreationWarrant(warrant) {
|
|
|
6753
6763
|
const u32 = (what) => view.getUint32(take(4, what).byteOffset, true);
|
|
6754
6764
|
const u64 = (what) => view.getBigUint64(take(8, what).byteOffset, true);
|
|
6755
6765
|
const option = (what) => {
|
|
6756
|
-
const
|
|
6757
|
-
if (
|
|
6758
|
-
if (
|
|
6766
|
+
const tag2 = take(1, what)[0];
|
|
6767
|
+
if (tag2 === 0) return null;
|
|
6768
|
+
if (tag2 !== 1) throw new Error(`${what} has option tag ${tag2}, expected 0 or 1`);
|
|
6759
6769
|
const len = u32(what);
|
|
6760
6770
|
if (len > MAX_LABEL_BYTES) {
|
|
6761
6771
|
throw new Error(`${what} is ${len} bytes, over the ${MAX_LABEL_BYTES} a node accepts`);
|
|
@@ -6807,6 +6817,134 @@ function borshOption(bytes) {
|
|
|
6807
6817
|
return concat(new Uint8Array([1]), u32le(bytes.length), bytes);
|
|
6808
6818
|
}
|
|
6809
6819
|
|
|
6820
|
+
// src/warrant/governance-warrant.ts
|
|
6821
|
+
var SIGN_DOMAIN4 = new TextEncoder().encode("calimero.governance-warrant.v1");
|
|
6822
|
+
var OP_DOMAIN = new TextEncoder().encode("calimero.governance-warrant.op.v1");
|
|
6823
|
+
var KIND_BYTE = { group: 0, root: 1 };
|
|
6824
|
+
async function governanceOpHash(op) {
|
|
6825
|
+
return domainHash(OP_DOMAIN, [new Uint8Array([kindByte(op.kind)]), op.bytes]);
|
|
6826
|
+
}
|
|
6827
|
+
async function governanceWarrantPreimage(p) {
|
|
6828
|
+
return domainHash(SIGN_DOMAIN4, [
|
|
6829
|
+
p.scope,
|
|
6830
|
+
new Uint8Array([kindByte(p.kind)]),
|
|
6831
|
+
p.authorAccount,
|
|
6832
|
+
p.deviceKey,
|
|
6833
|
+
p.executor,
|
|
6834
|
+
p.opHash,
|
|
6835
|
+
u64le(p.accountHeads.length),
|
|
6836
|
+
...p.accountHeads,
|
|
6837
|
+
u64le(p.governanceFloor.length),
|
|
6838
|
+
...p.governanceFloor,
|
|
6839
|
+
u64le(p.nonce),
|
|
6840
|
+
u64le(p.notAfter)
|
|
6841
|
+
]);
|
|
6842
|
+
}
|
|
6843
|
+
async function signGovernanceWarrant(input) {
|
|
6844
|
+
const scope = fromHex(input.scope, "scope", 32);
|
|
6845
|
+
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
6846
|
+
const executor = fromHex(input.executor, "executor", 32);
|
|
6847
|
+
const accountHeads = citedHeads(input.accountHeads, "accountHeads");
|
|
6848
|
+
const governanceFloor = citedHeads(input.governanceFloor, "governanceFloor");
|
|
6849
|
+
const kind = kindByte(input.op.kind);
|
|
6850
|
+
const key = await importSigningKey(input.deviceSecret);
|
|
6851
|
+
const deviceKey = await derivePublicKey(input.deviceSecret);
|
|
6852
|
+
const opHash = await governanceOpHash(input.op);
|
|
6853
|
+
const preimage = await governanceWarrantPreimage({
|
|
6854
|
+
scope,
|
|
6855
|
+
kind: input.op.kind,
|
|
6856
|
+
authorAccount,
|
|
6857
|
+
deviceKey,
|
|
6858
|
+
executor,
|
|
6859
|
+
opHash,
|
|
6860
|
+
accountHeads,
|
|
6861
|
+
governanceFloor,
|
|
6862
|
+
nonce: input.nonce,
|
|
6863
|
+
notAfter: input.notAfter
|
|
6864
|
+
});
|
|
6865
|
+
const signature = new Uint8Array(
|
|
6866
|
+
await crypto.subtle.sign({ name: "Ed25519" }, key, preimage)
|
|
6867
|
+
);
|
|
6868
|
+
return hex(
|
|
6869
|
+
concat(
|
|
6870
|
+
scope,
|
|
6871
|
+
new Uint8Array([kind]),
|
|
6872
|
+
authorAccount,
|
|
6873
|
+
deviceKey,
|
|
6874
|
+
executor,
|
|
6875
|
+
opHash,
|
|
6876
|
+
u32le(accountHeads.length),
|
|
6877
|
+
...accountHeads,
|
|
6878
|
+
u32le(governanceFloor.length),
|
|
6879
|
+
...governanceFloor,
|
|
6880
|
+
u64le(input.nonce),
|
|
6881
|
+
u64le(input.notAfter),
|
|
6882
|
+
signature
|
|
6883
|
+
)
|
|
6884
|
+
);
|
|
6885
|
+
}
|
|
6886
|
+
function parseGovernanceWarrant(warrant) {
|
|
6887
|
+
const clean = warrant.trim();
|
|
6888
|
+
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length % 2 !== 0) {
|
|
6889
|
+
throw new Error("governance warrant must be an even number of hex characters");
|
|
6890
|
+
}
|
|
6891
|
+
const bytes = new Uint8Array(clean.length / 2);
|
|
6892
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
6893
|
+
bytes[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
6894
|
+
}
|
|
6895
|
+
const view = new DataView(bytes.buffer);
|
|
6896
|
+
let o = 0;
|
|
6897
|
+
const take = (n, what) => {
|
|
6898
|
+
if (o + n > bytes.length) {
|
|
6899
|
+
throw new Error(`governance warrant ends inside ${what} (${bytes.length} bytes)`);
|
|
6900
|
+
}
|
|
6901
|
+
const out = bytes.subarray(o, o + n);
|
|
6902
|
+
o += n;
|
|
6903
|
+
return out;
|
|
6904
|
+
};
|
|
6905
|
+
const u32 = (what) => view.getUint32(take(4, what).byteOffset, true);
|
|
6906
|
+
const u64 = (what) => view.getBigUint64(take(8, what).byteOffset, true);
|
|
6907
|
+
const heads = (what) => {
|
|
6908
|
+
const count = u32(what);
|
|
6909
|
+
if (count > 64) {
|
|
6910
|
+
throw new Error(`${what} cites ${count} heads, over the 64 a node accepts`);
|
|
6911
|
+
}
|
|
6912
|
+
return Array.from({ length: count }, () => hex(take(32, what)));
|
|
6913
|
+
};
|
|
6914
|
+
const kind = () => {
|
|
6915
|
+
const byte = take(1, "kind")[0];
|
|
6916
|
+
if (byte === 0) return "group";
|
|
6917
|
+
if (byte === 1) return "root";
|
|
6918
|
+
throw new Error(`governance warrant has kind ${byte}, expected 0 (group) or 1 (root)`);
|
|
6919
|
+
};
|
|
6920
|
+
const fields = {
|
|
6921
|
+
scope: hex(take(32, "scope")),
|
|
6922
|
+
kind: kind(),
|
|
6923
|
+
authorAccount: hex(take(32, "authorAccount")),
|
|
6924
|
+
deviceKey: hex(take(32, "deviceKey")),
|
|
6925
|
+
executor: hex(take(32, "executor")),
|
|
6926
|
+
opHash: hex(take(32, "opHash")),
|
|
6927
|
+
accountHeads: heads("accountHeads"),
|
|
6928
|
+
governanceFloor: heads("governanceFloor"),
|
|
6929
|
+
nonce: u64("nonce"),
|
|
6930
|
+
notAfter: u64("notAfter"),
|
|
6931
|
+
signature: hex(take(64, "signature"))
|
|
6932
|
+
};
|
|
6933
|
+
if (o !== bytes.length) {
|
|
6934
|
+
throw new Error(
|
|
6935
|
+
`governance warrant is ${bytes.length} bytes but its fields account for ${o}`
|
|
6936
|
+
);
|
|
6937
|
+
}
|
|
6938
|
+
return fields;
|
|
6939
|
+
}
|
|
6940
|
+
function kindByte(kind) {
|
|
6941
|
+
const byte = KIND_BYTE[kind];
|
|
6942
|
+
if (byte === void 0) {
|
|
6943
|
+
throw new Error(`op kind must be 'group' or 'root', got ${String(kind)}`);
|
|
6944
|
+
}
|
|
6945
|
+
return byte;
|
|
6946
|
+
}
|
|
6947
|
+
|
|
6810
6948
|
// src/relay/relay-client.ts
|
|
6811
6949
|
var DEFAULT_TTL_SECONDS = 300;
|
|
6812
6950
|
var IntentRefusedError = class extends Error {
|
|
@@ -6920,14 +7058,7 @@ var RelayClient = class {
|
|
|
6920
7058
|
403
|
|
6921
7059
|
);
|
|
6922
7060
|
}
|
|
6923
|
-
const
|
|
6924
|
-
if (configured && configured.toLowerCase() !== described.executorAccount.toLowerCase()) {
|
|
6925
|
-
throw new Error(
|
|
6926
|
-
`configured executorAccount ${configured} is not the relay's account ${described.executorAccount}; a warrant naming it would be unspendable`
|
|
6927
|
-
);
|
|
6928
|
-
}
|
|
6929
|
-
const executor = described.executorAccount;
|
|
6930
|
-
this.executorAccount = executor;
|
|
7061
|
+
const executor = this.checkedExecutor(described.executorAccount);
|
|
6931
7062
|
const initArgs = input.initArgs ?? {};
|
|
6932
7063
|
const nonce2 = await this.config.nonces.next();
|
|
6933
7064
|
const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
@@ -6955,6 +7086,75 @@ var RelayClient = class {
|
|
|
6955
7086
|
memberPublicKey: body.data.memberPublicKey
|
|
6956
7087
|
};
|
|
6957
7088
|
}
|
|
7089
|
+
/**
|
|
7090
|
+
* Ask the relay whether it may publish governance ops for members of
|
|
7091
|
+
* `groupId`, and which account a warrant must name.
|
|
7092
|
+
*/
|
|
7093
|
+
async describeGovernance(groupId) {
|
|
7094
|
+
const body = await this.json(
|
|
7095
|
+
"GET",
|
|
7096
|
+
`/admin-api/groups/${encodeURIComponent(groupId)}/governance-intents`
|
|
7097
|
+
);
|
|
7098
|
+
return body.data;
|
|
7099
|
+
}
|
|
7100
|
+
/**
|
|
7101
|
+
* Publish one governance op through the relay, as the author.
|
|
7102
|
+
*
|
|
7103
|
+
* The warrant commits to the op's exact bytes and is scoped to `groupId`, so
|
|
7104
|
+
* the relay can neither change what the op does nor spend it elsewhere. Every
|
|
7105
|
+
* peer applies the op as the author, so the author's own rights decide
|
|
7106
|
+
* (`MANAGE_MEMBERS` to add a member, `CAN_CREATE_SUBGROUP` to create a
|
|
7107
|
+
* subgroup, and so on); a lack of them comes back as an
|
|
7108
|
+
* {@link IntentRefusedError} from the relay.
|
|
7109
|
+
*
|
|
7110
|
+
* Always asks {@link describeGovernance} first and refuses *before* taking a
|
|
7111
|
+
* nonce when the relay has no standing, for the reason `createContext` does.
|
|
7112
|
+
* The nonce comes from the configured {@link NonceSource}; it is spent in a
|
|
7113
|
+
* per-group ledger, and a monotonic source is correct for it as for every
|
|
7114
|
+
* other warrant.
|
|
7115
|
+
*/
|
|
7116
|
+
async govern(input) {
|
|
7117
|
+
const described = await this.describeGovernance(input.groupId);
|
|
7118
|
+
if (!described.canActOnBehalf) {
|
|
7119
|
+
throw new IntentRefusedError(
|
|
7120
|
+
`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)`,
|
|
7121
|
+
false,
|
|
7122
|
+
403
|
|
7123
|
+
);
|
|
7124
|
+
}
|
|
7125
|
+
const executor = this.checkedExecutor(described.executorAccount);
|
|
7126
|
+
const nonce2 = await this.config.nonces.next();
|
|
7127
|
+
const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
7128
|
+
const warrant = await signGovernanceWarrant({
|
|
7129
|
+
scope: input.groupId,
|
|
7130
|
+
op: input.op,
|
|
7131
|
+
authorAccount: this.config.authorAccount,
|
|
7132
|
+
executor,
|
|
7133
|
+
nonce: nonce2,
|
|
7134
|
+
notAfter: BigInt(Math.floor(Date.now() / 1e3)) + BigInt(ttl),
|
|
7135
|
+
deviceSecret: this.config.deviceSecret
|
|
7136
|
+
});
|
|
7137
|
+
const body = await this.json(
|
|
7138
|
+
"POST",
|
|
7139
|
+
`/admin-api/groups/${encodeURIComponent(input.groupId)}/governance-intents`,
|
|
7140
|
+
{ warrant, authorProof: this.config.authorProof, op: hex(input.op.bytes) }
|
|
7141
|
+
);
|
|
7142
|
+
return { groupId: body.data.groupId };
|
|
7143
|
+
}
|
|
7144
|
+
/**
|
|
7145
|
+
* The executor a warrant must name: the one the relay answered with, which a
|
|
7146
|
+
* configured account must agree with. Remembered for later calls.
|
|
7147
|
+
*/
|
|
7148
|
+
checkedExecutor(answered) {
|
|
7149
|
+
const configured = this.config.executorAccount;
|
|
7150
|
+
if (configured && configured.toLowerCase() !== answered.toLowerCase()) {
|
|
7151
|
+
throw new Error(
|
|
7152
|
+
`configured executorAccount ${configured} is not the relay's account ${answered}; a warrant naming it would be unspendable`
|
|
7153
|
+
);
|
|
7154
|
+
}
|
|
7155
|
+
this.executorAccount = answered;
|
|
7156
|
+
return answered;
|
|
7157
|
+
}
|
|
6958
7158
|
async json(method, path, body) {
|
|
6959
7159
|
const headers = { Accept: "application/json" };
|
|
6960
7160
|
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
@@ -7841,8 +8041,8 @@ var SIGNATURE_HASHES = {
|
|
|
7841
8041
|
};
|
|
7842
8042
|
function read(bytes, offset, limit) {
|
|
7843
8043
|
if (offset + 2 > limit) throw new Error("it is truncated");
|
|
7844
|
-
const
|
|
7845
|
-
if ((
|
|
8044
|
+
const tag2 = bytes[offset];
|
|
8045
|
+
if ((tag2 & 31) === 31) throw new Error("it uses a tag this parser does not read");
|
|
7846
8046
|
let length = bytes[offset + 1];
|
|
7847
8047
|
let start = offset + 2;
|
|
7848
8048
|
if (length & 128) {
|
|
@@ -7854,7 +8054,7 @@ function read(bytes, offset, limit) {
|
|
|
7854
8054
|
}
|
|
7855
8055
|
const end = start + length;
|
|
7856
8056
|
if (end > limit) throw new Error("it is truncated");
|
|
7857
|
-
return { tag, bytes, offset, start, end };
|
|
8057
|
+
return { tag: tag2, bytes, offset, start, end };
|
|
7858
8058
|
}
|
|
7859
8059
|
function parseDer(bytes) {
|
|
7860
8060
|
const element = read(bytes, 0, bytes.length);
|
|
@@ -7870,8 +8070,8 @@ function children(element) {
|
|
|
7870
8070
|
}
|
|
7871
8071
|
return out;
|
|
7872
8072
|
}
|
|
7873
|
-
function expectTag(element,
|
|
7874
|
-
if (!element || element.tag !==
|
|
8073
|
+
function expectTag(element, tag2, what) {
|
|
8074
|
+
if (!element || element.tag !== tag2) throw new Error(`${what} is not where it should be`);
|
|
7875
8075
|
return element;
|
|
7876
8076
|
}
|
|
7877
8077
|
function contents(element) {
|
|
@@ -8333,11 +8533,103 @@ function splitVersion2(version) {
|
|
|
8333
8533
|
return [[Number(match[1]), Number(match[2]), Number(match[3])], match[4]];
|
|
8334
8534
|
}
|
|
8335
8535
|
|
|
8536
|
+
// src/warrant/governance-op.ts
|
|
8537
|
+
var ROLE = {
|
|
8538
|
+
Admin: 0,
|
|
8539
|
+
Member: 1,
|
|
8540
|
+
ReadOnly: 2
|
|
8541
|
+
};
|
|
8542
|
+
var GROUP_OP = {
|
|
8543
|
+
MemberAdded: 1,
|
|
8544
|
+
MemberRemoved: 2,
|
|
8545
|
+
MemberLeft: 3,
|
|
8546
|
+
MemberRoleSet: 4
|
|
8547
|
+
};
|
|
8548
|
+
var ROOT_OP = {
|
|
8549
|
+
GroupCreated: 0,
|
|
8550
|
+
GroupReparented: 1,
|
|
8551
|
+
GroupDeleted: 2
|
|
8552
|
+
};
|
|
8553
|
+
var CLEARED_HASH = new Uint8Array(32);
|
|
8554
|
+
var EMPTY_VEC = u32le(0);
|
|
8555
|
+
function role(value) {
|
|
8556
|
+
const byte = ROLE[value];
|
|
8557
|
+
if (byte === void 0) {
|
|
8558
|
+
throw new Error(`role must be Admin, Member or ReadOnly, got ${String(value)}`);
|
|
8559
|
+
}
|
|
8560
|
+
return new Uint8Array([byte]);
|
|
8561
|
+
}
|
|
8562
|
+
function tag(byte) {
|
|
8563
|
+
return new Uint8Array([byte]);
|
|
8564
|
+
}
|
|
8565
|
+
function memberAddedOp(member, memberRole) {
|
|
8566
|
+
return {
|
|
8567
|
+
kind: "group",
|
|
8568
|
+
bytes: concat(tag(GROUP_OP.MemberAdded), fromHex(member, "member", 32), role(memberRole))
|
|
8569
|
+
};
|
|
8570
|
+
}
|
|
8571
|
+
function memberRemovedOp(member) {
|
|
8572
|
+
return {
|
|
8573
|
+
kind: "group",
|
|
8574
|
+
bytes: concat(
|
|
8575
|
+
tag(GROUP_OP.MemberRemoved),
|
|
8576
|
+
fromHex(member, "member", 32),
|
|
8577
|
+
CLEARED_HASH,
|
|
8578
|
+
EMPTY_VEC
|
|
8579
|
+
)
|
|
8580
|
+
};
|
|
8581
|
+
}
|
|
8582
|
+
function memberLeftOp(member) {
|
|
8583
|
+
return {
|
|
8584
|
+
kind: "group",
|
|
8585
|
+
bytes: concat(
|
|
8586
|
+
tag(GROUP_OP.MemberLeft),
|
|
8587
|
+
fromHex(member, "member", 32),
|
|
8588
|
+
CLEARED_HASH,
|
|
8589
|
+
EMPTY_VEC
|
|
8590
|
+
)
|
|
8591
|
+
};
|
|
8592
|
+
}
|
|
8593
|
+
function memberRoleSetOp(member, memberRole) {
|
|
8594
|
+
return {
|
|
8595
|
+
kind: "group",
|
|
8596
|
+
bytes: concat(tag(GROUP_OP.MemberRoleSet), fromHex(member, "member", 32), role(memberRole))
|
|
8597
|
+
};
|
|
8598
|
+
}
|
|
8599
|
+
function groupCreatedOp(input) {
|
|
8600
|
+
return {
|
|
8601
|
+
kind: "root",
|
|
8602
|
+
bytes: concat(
|
|
8603
|
+
tag(ROOT_OP.GroupCreated),
|
|
8604
|
+
fromHex(input.groupId, "groupId", 32),
|
|
8605
|
+
fromHex(input.parentId, "parentId", 32),
|
|
8606
|
+
tag(input.restricted ? 1 : 0),
|
|
8607
|
+
fromHex(input.admin, "admin", 32)
|
|
8608
|
+
)
|
|
8609
|
+
};
|
|
8610
|
+
}
|
|
8611
|
+
function groupReparentedOp(childGroupId, newParentId) {
|
|
8612
|
+
return {
|
|
8613
|
+
kind: "root",
|
|
8614
|
+
bytes: concat(
|
|
8615
|
+
tag(ROOT_OP.GroupReparented),
|
|
8616
|
+
fromHex(childGroupId, "childGroupId", 32),
|
|
8617
|
+
fromHex(newParentId, "newParentId", 32)
|
|
8618
|
+
)
|
|
8619
|
+
};
|
|
8620
|
+
}
|
|
8621
|
+
function groupDeletedOp(rootGroupId) {
|
|
8622
|
+
return {
|
|
8623
|
+
kind: "root",
|
|
8624
|
+
bytes: concat(tag(ROOT_OP.GroupDeleted), fromHex(rootGroupId, "rootGroupId", 32), EMPTY_VEC, EMPTY_VEC)
|
|
8625
|
+
};
|
|
8626
|
+
}
|
|
8627
|
+
|
|
8336
8628
|
// src/namespace-op/namespace-op.ts
|
|
8337
|
-
var SIGNED_NAMESPACE_OP_SCHEMA_VERSION =
|
|
8629
|
+
var SIGNED_NAMESPACE_OP_SCHEMA_VERSION = 15;
|
|
8338
8630
|
var NAMESPACE_SIGN_DOMAIN = new TextEncoder().encode("calimero.namespace.v1");
|
|
8339
8631
|
var NAMESPACE_OP_ROOT = 0;
|
|
8340
|
-
var
|
|
8632
|
+
var ROOT_OP2 = {
|
|
8341
8633
|
GroupCreated: 0,
|
|
8342
8634
|
GroupReparented: 1,
|
|
8343
8635
|
GroupDeleted: 2,
|
|
@@ -8412,13 +8704,13 @@ async function signMemberJoinOp(input) {
|
|
|
8412
8704
|
const expires = BigInt(input.invitation.invitation.expiration_timestamp ?? 0) !== 0n;
|
|
8413
8705
|
const joinedAt = input.joinedAt ?? BigInt(Math.floor(Date.now() / 1e3));
|
|
8414
8706
|
const rootOp = expires ? concat(
|
|
8415
|
-
new Uint8Array([
|
|
8707
|
+
new Uint8Array([ROOT_OP2.MemberJoinedAt]),
|
|
8416
8708
|
fromHex(input.member, "member", 32),
|
|
8417
8709
|
encodeSignedInvitation(input.invitation),
|
|
8418
8710
|
u64le(joinedAt),
|
|
8419
8711
|
credential
|
|
8420
8712
|
) : concat(
|
|
8421
|
-
new Uint8Array([
|
|
8713
|
+
new Uint8Array([ROOT_OP2.MemberJoined]),
|
|
8422
8714
|
fromHex(input.member, "member", 32),
|
|
8423
8715
|
encodeSignedInvitation(input.invitation),
|
|
8424
8716
|
credential
|
|
@@ -8443,7 +8735,7 @@ async function signMemberJoinOp(input) {
|
|
|
8443
8735
|
}
|
|
8444
8736
|
|
|
8445
8737
|
// src/login/login.ts
|
|
8446
|
-
var
|
|
8738
|
+
var SIGN_DOMAIN5 = new TextEncoder().encode("calimero.auth.login.v1");
|
|
8447
8739
|
var AUDIENCE_TAG = {
|
|
8448
8740
|
webOrigin: 0,
|
|
8449
8741
|
codeSigningId: 1,
|
|
@@ -8467,12 +8759,12 @@ function audienceSigningBytes(audience) {
|
|
|
8467
8759
|
);
|
|
8468
8760
|
}
|
|
8469
8761
|
function audienceWire(audience) {
|
|
8470
|
-
const
|
|
8762
|
+
const tag2 = Uint8Array.from([AUDIENCE_TAG[audience.kind]]);
|
|
8471
8763
|
if (audience.kind === "cli") {
|
|
8472
|
-
return
|
|
8764
|
+
return tag2;
|
|
8473
8765
|
}
|
|
8474
8766
|
const body = audienceBody(audience);
|
|
8475
|
-
return concat(
|
|
8767
|
+
return concat(tag2, u32le(body.length), body);
|
|
8476
8768
|
}
|
|
8477
8769
|
async function signLoginStatement(input) {
|
|
8478
8770
|
const node = fromHex(input.node, "node", 32);
|
|
@@ -8482,7 +8774,7 @@ async function signLoginStatement(input) {
|
|
|
8482
8774
|
const deviceKey = await derivePublicKey(input.deviceSecret);
|
|
8483
8775
|
const issuedAt = u64le(input.issuedAt);
|
|
8484
8776
|
const expiresAt = u64le(input.expiresAt);
|
|
8485
|
-
const preimage = await domainHash(
|
|
8777
|
+
const preimage = await domainHash(SIGN_DOMAIN5, [
|
|
8486
8778
|
node,
|
|
8487
8779
|
audienceSigningBytes(input.audience),
|
|
8488
8780
|
challenge,
|