@invisi-labs/sdk 1.1.7 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/broadcaster-3KTB4JO2.cjs +21 -0
- package/dist/broadcaster-3KTB4JO2.cjs.map +1 -0
- package/dist/broadcaster-7ZKKSTZQ.js +21 -0
- package/dist/broadcaster-preparation-PJ263WBL.cjs +15 -0
- package/dist/broadcaster-preparation-PJ263WBL.cjs.map +1 -0
- package/dist/broadcaster-preparation-ZQAPZAUG.js +15 -0
- package/dist/broadcaster-preparation-ZQAPZAUG.js.map +1 -0
- package/dist/{chunk-LOU7AP2B.cjs → chunk-2URICDPW.cjs} +72 -33
- package/dist/chunk-2URICDPW.cjs.map +1 -0
- package/dist/chunk-3D24ABYR.js +86 -0
- package/dist/chunk-3D24ABYR.js.map +1 -0
- package/dist/chunk-3KTQQZOW.cjs +71 -0
- package/dist/chunk-3KTQQZOW.cjs.map +1 -0
- package/dist/chunk-4SDP53YQ.cjs +765 -0
- package/dist/chunk-4SDP53YQ.cjs.map +1 -0
- package/dist/{chunk-XHKQ2BO2.js → chunk-4VI6LYGH.js} +25 -2
- package/dist/chunk-4VI6LYGH.js.map +1 -0
- package/dist/chunk-BBSRP4MH.cjs +287 -0
- package/dist/chunk-BBSRP4MH.cjs.map +1 -0
- package/dist/chunk-DGMVGFKM.js +41 -0
- package/dist/chunk-DGMVGFKM.js.map +1 -0
- package/dist/chunk-DHQEB6JR.cjs +1616 -0
- package/dist/chunk-DHQEB6JR.cjs.map +1 -0
- package/dist/chunk-FKF67XE6.js +1616 -0
- package/dist/chunk-FKF67XE6.js.map +1 -0
- package/dist/chunk-GUD3LAUO.js +765 -0
- package/dist/chunk-GUD3LAUO.js.map +1 -0
- package/dist/chunk-HCB7RQ3S.cjs +79 -0
- package/dist/chunk-HCB7RQ3S.cjs.map +1 -0
- package/dist/{chunk-GTPUYPQL.js → chunk-HKGJXQVN.js} +69 -30
- package/dist/chunk-HKGJXQVN.js.map +1 -0
- package/dist/chunk-HLH5JZD4.js +287 -0
- package/dist/chunk-HLH5JZD4.js.map +1 -0
- package/dist/chunk-J6TZZVAM.cjs +230 -0
- package/dist/chunk-J6TZZVAM.cjs.map +1 -0
- package/dist/{chunk-7F7ZZW3L.cjs → chunk-LOR6PYH5.cjs} +25 -2
- package/dist/chunk-LOR6PYH5.cjs.map +1 -0
- package/dist/chunk-MA2QZEF5.cjs +399 -0
- package/dist/chunk-MA2QZEF5.cjs.map +1 -0
- package/dist/chunk-MI4IP4ZD.cjs +86 -0
- package/dist/chunk-MI4IP4ZD.cjs.map +1 -0
- package/dist/chunk-OCZLJKIA.cjs +41 -0
- package/dist/chunk-OCZLJKIA.cjs.map +1 -0
- package/dist/chunk-R5YAOJKB.js +71 -0
- package/dist/chunk-R5YAOJKB.js.map +1 -0
- package/dist/chunk-RY4M2CIQ.js +399 -0
- package/dist/chunk-RY4M2CIQ.js.map +1 -0
- package/dist/chunk-THMD5QO2.js +79 -0
- package/dist/chunk-THMD5QO2.js.map +1 -0
- package/dist/chunk-ZD2652WH.js +230 -0
- package/dist/chunk-ZD2652WH.js.map +1 -0
- package/dist/credit.cjs +1 -0
- package/dist/credit.cjs.map +1 -0
- package/dist/credit.d.cts +12 -0
- package/dist/credit.d.ts +12 -0
- package/dist/credit.js +1 -0
- package/dist/credit.js.map +1 -0
- package/dist/ethers.cjs +2 -2
- package/dist/ethers.cjs.map +1 -1
- package/dist/ethers.d.cts +15 -4
- package/dist/ethers.d.ts +15 -4
- package/dist/ethers.js +1 -1
- package/dist/index-CLhGwLxZ.d.cts +42 -0
- package/dist/index-Crp-ZFiM.d.ts +42 -0
- package/dist/index.cjs +69 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -14
- package/dist/index.d.ts +21 -14
- package/dist/index.js +64 -33
- package/dist/index.js.map +1 -1
- package/dist/note.cjs +11 -0
- package/dist/note.cjs.map +1 -0
- package/dist/note.d.cts +29 -0
- package/dist/note.d.ts +29 -0
- package/dist/note.js +11 -0
- package/dist/note.js.map +1 -0
- package/dist/{broadcaster-preparation-DMxxZ_1Q.d.cts → operation-bridge-CoECSxfi.d.cts} +130 -245
- package/dist/{broadcaster-preparation-DMxxZ_1Q.d.ts → operation-bridge-CoECSxfi.d.ts} +130 -245
- package/dist/preparation-HUBTVCZE.js +404 -0
- package/dist/preparation-HUBTVCZE.js.map +1 -0
- package/dist/preparation-QD3ZSYV5.cjs +404 -0
- package/dist/preparation-QD3ZSYV5.cjs.map +1 -0
- package/dist/provenance-preparation-43DN2WK7.cjs +16 -0
- package/dist/provenance-preparation-43DN2WK7.cjs.map +1 -0
- package/dist/provenance-preparation-HEZE4L5H.js +16 -0
- package/dist/provenance-preparation-HEZE4L5H.js.map +1 -0
- package/dist/provenance.cjs +59 -0
- package/dist/provenance.cjs.map +1 -0
- package/dist/provenance.d.cts +34 -0
- package/dist/provenance.d.ts +34 -0
- package/dist/provenance.js +59 -0
- package/dist/provenance.js.map +1 -0
- package/dist/{receipt-logs-m0-bhaxW.d.ts → receipt-logs-DQRJK0l8.d.cts} +84 -78
- package/dist/{receipt-logs-CvC951p7.d.cts → receipt-logs-fMR6Bwql.d.ts} +84 -78
- package/dist/session-support.cjs +28 -7
- package/dist/session-support.cjs.map +1 -1
- package/dist/session-support.d.cts +71 -39
- package/dist/session-support.d.ts +71 -39
- package/dist/session-support.js +58 -37
- package/dist/session-support.js.map +1 -1
- package/package.json +22 -6
- package/dist/broadcaster-preparation-RMWQFYNL.js +0 -11
- package/dist/broadcaster-preparation-UGOTO4SX.cjs +0 -11
- package/dist/broadcaster-preparation-UGOTO4SX.cjs.map +0 -1
- package/dist/chunk-7F7ZZW3L.cjs.map +0 -1
- package/dist/chunk-EHP5TBC6.js +0 -3565
- package/dist/chunk-EHP5TBC6.js.map +0 -1
- package/dist/chunk-GTPUYPQL.js.map +0 -1
- package/dist/chunk-ITTGBIG2.js +0 -1877
- package/dist/chunk-ITTGBIG2.js.map +0 -1
- package/dist/chunk-J2JH6HIG.cjs +0 -1877
- package/dist/chunk-J2JH6HIG.cjs.map +0 -1
- package/dist/chunk-LOU7AP2B.cjs.map +0 -1
- package/dist/chunk-RHNIHI4P.cjs +0 -3565
- package/dist/chunk-RHNIHI4P.cjs.map +0 -1
- package/dist/chunk-XHKQ2BO2.js.map +0 -1
- /package/dist/{broadcaster-preparation-RMWQFYNL.js.map → broadcaster-7ZKKSTZQ.js.map} +0 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import {
|
|
2
|
+
statement
|
|
3
|
+
} from "./chunk-THMD5QO2.js";
|
|
4
|
+
import {
|
|
5
|
+
Preparation,
|
|
6
|
+
positiveAmount,
|
|
7
|
+
positiveOutputAmount
|
|
8
|
+
} from "./chunk-RY4M2CIQ.js";
|
|
9
|
+
import {
|
|
10
|
+
resolvedOutputSnapshot
|
|
11
|
+
} from "./chunk-GUD3LAUO.js";
|
|
12
|
+
|
|
13
|
+
// src/broadcaster/intent.ts
|
|
14
|
+
import { normalizeFunding } from "@invisi-labs/protocol";
|
|
15
|
+
import { invisiProtocolAbi } from "@invisi-labs/protocol/contracts";
|
|
16
|
+
import { Interface } from "ethers";
|
|
17
|
+
function exportBroadcasterIntent(plan) {
|
|
18
|
+
if (plan.statement && plan.statement.target !== "evm")
|
|
19
|
+
throw new Error("unsupported broadcaster operation");
|
|
20
|
+
if (plan.statement) statement(plan);
|
|
21
|
+
const feeDefaults = (params) => ({
|
|
22
|
+
...params,
|
|
23
|
+
feeRecipient: params.feeRecipient ?? "0x0000000000000000000000000000000000000000",
|
|
24
|
+
feeAmount: params.feeAmount ?? 0n
|
|
25
|
+
});
|
|
26
|
+
const funding = { ...normalizeFunding(plan.funding), signature: "0x" };
|
|
27
|
+
let method;
|
|
28
|
+
let args;
|
|
29
|
+
if (plan.params) {
|
|
30
|
+
method = "transact";
|
|
31
|
+
args = [
|
|
32
|
+
"0x",
|
|
33
|
+
{
|
|
34
|
+
params: feeDefaults(plan.params),
|
|
35
|
+
deliveries: plan.outputs.map((o) => o.delivery),
|
|
36
|
+
funding
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
} else if (plan.shieldParams) {
|
|
40
|
+
method = "shield";
|
|
41
|
+
args = [
|
|
42
|
+
feeDefaults(plan.shieldParams),
|
|
43
|
+
plan.shieldOutputs,
|
|
44
|
+
plan.outputs.map((o) => o.delivery),
|
|
45
|
+
funding
|
|
46
|
+
];
|
|
47
|
+
} else if (plan.credit?.creation) {
|
|
48
|
+
method = "createCredit";
|
|
49
|
+
args = ["0x", plan.credit.creation, plan.credit.deliveries];
|
|
50
|
+
} else if (plan.credit?.draw) {
|
|
51
|
+
method = "creditDraw";
|
|
52
|
+
args = ["0x", plan.credit.draw, plan.credit.deliveries];
|
|
53
|
+
} else if (plan.credit?.update) {
|
|
54
|
+
method = "updateCredit";
|
|
55
|
+
args = ["0x", plan.credit.update, plan.credit.deliveries];
|
|
56
|
+
} else if (plan.credit?.revocation) {
|
|
57
|
+
const p = plan.credit.revocation;
|
|
58
|
+
method = "revokeCredit";
|
|
59
|
+
args = [
|
|
60
|
+
p.token,
|
|
61
|
+
p.owner,
|
|
62
|
+
p.shard,
|
|
63
|
+
p.slot,
|
|
64
|
+
p.deadline,
|
|
65
|
+
p.feeRecipient ?? "0x0000000000000000000000000000000000000000",
|
|
66
|
+
p.feeAmount ?? 0n,
|
|
67
|
+
"0x"
|
|
68
|
+
];
|
|
69
|
+
} else throw new Error("unsupported broadcaster operation");
|
|
70
|
+
const abi = invisiProtocolAbi.filter(
|
|
71
|
+
(item) => item.type === "function" && item.name === method && (method !== "transact" || item.inputs[1]?.type === "tuple")
|
|
72
|
+
);
|
|
73
|
+
return {
|
|
74
|
+
sendable: false,
|
|
75
|
+
data: new Interface(abi).encodeFunctionData(method, args)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/transactions/preparation/transaction-preparation.ts
|
|
80
|
+
import {
|
|
81
|
+
normalizeTransactRequest,
|
|
82
|
+
transactUserPublicInputs,
|
|
83
|
+
ZERO_ADDRESS
|
|
84
|
+
} from "@invisi-labs/protocol";
|
|
85
|
+
import { WitnessBuilder } from "@invisi-labs/prover";
|
|
86
|
+
import { getAddress } from "ethers";
|
|
87
|
+
var TransactionPreparation = class {
|
|
88
|
+
constructor(context) {
|
|
89
|
+
this.context = context;
|
|
90
|
+
const complete = context.complete;
|
|
91
|
+
this.context = {
|
|
92
|
+
...context,
|
|
93
|
+
complete: (plan) => {
|
|
94
|
+
const intent = this.#intent ? structuredClone(this.#intent) : void 0;
|
|
95
|
+
if (intent && (intent.kind === "transfer" || intent.kind === "shield")) {
|
|
96
|
+
const businessOutputs = plan.outputs.filter((output) => !output.change);
|
|
97
|
+
intent.options.outputs = intent.options.outputs.map(
|
|
98
|
+
(payment, index) => resolvedOutputSnapshot(payment, businessOutputs[index])
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return complete({ ...plan, ...intent ? { intent } : {} });
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
#intent;
|
|
106
|
+
runtime(tokenAddress) {
|
|
107
|
+
if (getAddress(tokenAddress) !== getAddress(this.context.options.protocol.context.tokenAddress))
|
|
108
|
+
throw new Error("preparation token mismatch");
|
|
109
|
+
return this.context;
|
|
110
|
+
}
|
|
111
|
+
get scope() {
|
|
112
|
+
return this.context.scope;
|
|
113
|
+
}
|
|
114
|
+
async prepareTransfer(options) {
|
|
115
|
+
this.#intent = { kind: "transfer", options: structuredClone(options) };
|
|
116
|
+
if (Object.hasOwn(options, "target") || Object.hasOwn(options, "execution")) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
"prepareTransfer accepts no target or execution; choose execution in prove()"
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
const copied = structuredClone(options);
|
|
122
|
+
const runtime = this.runtime(copied.tokenAddress);
|
|
123
|
+
if (copied.commitments !== void 0 && copied.commitments.length === 0)
|
|
124
|
+
throw new Error("empty explicit input selection");
|
|
125
|
+
const preparation = new Preparation({
|
|
126
|
+
...runtime,
|
|
127
|
+
...copied.commitments !== void 0 ? { inputSelection: copied.commitments } : {}
|
|
128
|
+
});
|
|
129
|
+
const frame = await preparation.frame(copied.deadline);
|
|
130
|
+
if (copied.outputs.length > 190) throw new Error("transfer supports at most 190 outputs");
|
|
131
|
+
let withdrawalAddress = ZERO_ADDRESS;
|
|
132
|
+
let withdrawalAmount = 0n;
|
|
133
|
+
if (copied.withdrawal !== void 0) {
|
|
134
|
+
withdrawalAddress = getAddress(copied.withdrawal.to);
|
|
135
|
+
positiveAmount(copied.withdrawal.amount);
|
|
136
|
+
if (BigInt(withdrawalAddress) === 0n)
|
|
137
|
+
throw new Error("withdrawal destination must be nonzero");
|
|
138
|
+
withdrawalAmount = copied.withdrawal.amount;
|
|
139
|
+
}
|
|
140
|
+
if (copied.outputs.length === 0 && withdrawalAmount === 0n)
|
|
141
|
+
throw new Error("transfer requires a private output or public withdrawal");
|
|
142
|
+
const feeRecipient = copied.fee ? getAddress(copied.fee.recipient) : ZERO_ADDRESS;
|
|
143
|
+
const feeAmount = copied.fee?.amount ?? 0n;
|
|
144
|
+
if (copied.fee) {
|
|
145
|
+
positiveAmount(feeAmount);
|
|
146
|
+
if (BigInt(feeRecipient) === 0n) throw new Error("fee recipient must be nonzero");
|
|
147
|
+
}
|
|
148
|
+
const total = copied.outputs.reduce(
|
|
149
|
+
(sum, output, index) => sum + positiveOutputAmount(output, index),
|
|
150
|
+
withdrawalAmount + feeAmount
|
|
151
|
+
);
|
|
152
|
+
const funding = await preparation.funding(copied.funding, frame);
|
|
153
|
+
return this.funds(
|
|
154
|
+
copied.outputs,
|
|
155
|
+
total,
|
|
156
|
+
withdrawalAddress,
|
|
157
|
+
withdrawalAmount,
|
|
158
|
+
{ recipient: feeRecipient, amount: feeAmount },
|
|
159
|
+
frame,
|
|
160
|
+
funding,
|
|
161
|
+
preparation
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
async funds(payments, total, withdrawalAddress, withdrawalAmount, fee, frame, funding, preparation) {
|
|
165
|
+
if (total >= 1n << 135n) {
|
|
166
|
+
throw new Error("transaction sum exceeds uint135");
|
|
167
|
+
}
|
|
168
|
+
const { context, block, deadline } = frame;
|
|
169
|
+
const selection = await preparation.selectFunds(
|
|
170
|
+
total - (funding.funding.amount ?? 0n),
|
|
171
|
+
frame
|
|
172
|
+
);
|
|
173
|
+
const outputs = await Promise.all(
|
|
174
|
+
payments.map((payment, index) => preparation.output(payment, context, false, index))
|
|
175
|
+
);
|
|
176
|
+
const change = selection.amount + (funding.funding.amount ?? 0n) - total;
|
|
177
|
+
if (change > 0n) {
|
|
178
|
+
outputs.push(await preparation.change(change, context));
|
|
179
|
+
}
|
|
180
|
+
const params = {
|
|
181
|
+
token: context.tokenAddress,
|
|
182
|
+
sources: selection.sources,
|
|
183
|
+
nullifiers: selection.nullifiers,
|
|
184
|
+
noteCommitments: outputs.map((output) => output.commitment),
|
|
185
|
+
withdrawalAddress,
|
|
186
|
+
withdrawalAmount,
|
|
187
|
+
deadline,
|
|
188
|
+
feeRecipient: fee.recipient,
|
|
189
|
+
feeAmount: fee.amount
|
|
190
|
+
};
|
|
191
|
+
const deliveries = outputs.map((output) => output.delivery);
|
|
192
|
+
const normalized = normalizeTransactRequest(context, params, deliveries, funding.funding);
|
|
193
|
+
const statement2 = WitnessBuilder.statement(
|
|
194
|
+
`transact_user_slots${normalized.capacity}`,
|
|
195
|
+
transactUserPublicInputs(context, params, deliveries, funding.funding),
|
|
196
|
+
"evm"
|
|
197
|
+
);
|
|
198
|
+
await preparation.assertBlock(frame);
|
|
199
|
+
return preparation.runtime.complete({
|
|
200
|
+
version: 1,
|
|
201
|
+
id: crypto.randomUUID(),
|
|
202
|
+
kind: "transfer",
|
|
203
|
+
context,
|
|
204
|
+
scope: this.scope,
|
|
205
|
+
preparedAt: block,
|
|
206
|
+
deadline,
|
|
207
|
+
outputs,
|
|
208
|
+
inputs: selection.inputs,
|
|
209
|
+
...funding,
|
|
210
|
+
params,
|
|
211
|
+
capacity: normalized.capacity,
|
|
212
|
+
statement: statement2
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async prepareShield(options) {
|
|
216
|
+
this.#intent = { kind: "shield", options: structuredClone(options) };
|
|
217
|
+
const copied = structuredClone(options);
|
|
218
|
+
const preparation = new Preparation(this.runtime(copied.tokenAddress));
|
|
219
|
+
const frame = await preparation.frame(copied.deadline);
|
|
220
|
+
const funding = await preparation.funding(copied.funding, frame);
|
|
221
|
+
if (copied.outputs.length < 1 || copied.outputs.length > 10) {
|
|
222
|
+
throw new Error("shield requires 1..10 outputs");
|
|
223
|
+
}
|
|
224
|
+
const outputs = await Promise.all(
|
|
225
|
+
copied.outputs.map(
|
|
226
|
+
(output, index) => preparation.output(output, frame.context, false, index)
|
|
227
|
+
)
|
|
228
|
+
);
|
|
229
|
+
if (outputs.reduce((sum, output) => sum + output.amount, 0n) !== (funding.funding.amount ?? 0n) - (copied.fee?.amount ?? 0n)) {
|
|
230
|
+
throw new Error("shield funding must equal output total");
|
|
231
|
+
}
|
|
232
|
+
await preparation.assertBlock(frame);
|
|
233
|
+
return preparation.runtime.complete({
|
|
234
|
+
version: 1,
|
|
235
|
+
id: crypto.randomUUID(),
|
|
236
|
+
kind: "shield",
|
|
237
|
+
context: frame.context,
|
|
238
|
+
scope: this.scope,
|
|
239
|
+
preparedAt: frame.block,
|
|
240
|
+
deadline: frame.deadline,
|
|
241
|
+
outputs,
|
|
242
|
+
inputs: [],
|
|
243
|
+
...funding,
|
|
244
|
+
shieldParams: {
|
|
245
|
+
token: frame.context.tokenAddress,
|
|
246
|
+
feeRecipient: copied.fee?.recipient ?? ZERO_ADDRESS,
|
|
247
|
+
feeAmount: copied.fee?.amount ?? 0n,
|
|
248
|
+
noteCommitments: outputs.map((output) => output.commitment),
|
|
249
|
+
deadline: frame.deadline
|
|
250
|
+
},
|
|
251
|
+
shieldOutputs: outputs.map((output) => ({
|
|
252
|
+
identity: output.identity,
|
|
253
|
+
amount: output.amount
|
|
254
|
+
}))
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
async prepareCreateCredit(options) {
|
|
258
|
+
const copied = structuredClone(options);
|
|
259
|
+
this.#intent = { kind: "create-credit", options: structuredClone(copied) };
|
|
260
|
+
const { CreditPreparation } = await import("./preparation-HUBTVCZE.js");
|
|
261
|
+
return new CreditPreparation(this.runtime(copied.tokenAddress)).create(copied);
|
|
262
|
+
}
|
|
263
|
+
async prepareDrawCredit(options) {
|
|
264
|
+
const copied = structuredClone(options);
|
|
265
|
+
this.#intent = { kind: "draw-credit", options: structuredClone(copied) };
|
|
266
|
+
const { CreditPreparation } = await import("./preparation-HUBTVCZE.js");
|
|
267
|
+
return new CreditPreparation(this.runtime(copied.tokenAddress)).draw(copied);
|
|
268
|
+
}
|
|
269
|
+
async prepareUpdateCredit(options) {
|
|
270
|
+
const copied = structuredClone(options);
|
|
271
|
+
this.#intent = { kind: "update-credit", options: structuredClone(copied) };
|
|
272
|
+
const { CreditPreparation } = await import("./preparation-HUBTVCZE.js");
|
|
273
|
+
return new CreditPreparation(this.runtime(copied.tokenAddress)).update(copied);
|
|
274
|
+
}
|
|
275
|
+
async prepareRevokeCredit(options) {
|
|
276
|
+
const copied = structuredClone(options);
|
|
277
|
+
this.#intent = { kind: "revoke-credit", options: structuredClone(copied) };
|
|
278
|
+
const { CreditPreparation } = await import("./preparation-HUBTVCZE.js");
|
|
279
|
+
return new CreditPreparation(this.runtime(copied.tokenAddress)).revoke(copied);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export {
|
|
284
|
+
exportBroadcasterIntent,
|
|
285
|
+
TransactionPreparation
|
|
286
|
+
};
|
|
287
|
+
//# sourceMappingURL=chunk-HLH5JZD4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/broadcaster/intent.ts","../src/transactions/preparation/transaction-preparation.ts"],"sourcesContent":["import { normalizeFunding } from \"@invisi-labs/protocol\";\nimport type { Hex } from \"@invisi-labs/protocol/contracts\";\nimport { invisiProtocolAbi } from \"@invisi-labs/protocol/contracts\";\nimport { Interface } from \"ethers\";\nimport type { OperationPlan } from \"../transactions/operation-types\";\nimport { statement } from \"../transactions/signing/statement\";\n\n/** Quote-only export; callers still need the operation-specific proof or owner authorization. */\nexport function exportBroadcasterIntent(plan: OperationPlan) {\n if (plan.statement && plan.statement.target !== \"evm\")\n throw new Error(\"unsupported broadcaster operation\");\n if (plan.statement) statement(plan);\n const feeDefaults = <T extends { feeRecipient?: string; feeAmount?: bigint }>(params: T) => ({\n ...params,\n feeRecipient: params.feeRecipient ?? \"0x0000000000000000000000000000000000000000\",\n feeAmount: params.feeAmount ?? 0n,\n });\n const funding = { ...normalizeFunding(plan.funding), signature: \"0x\" };\n let method: string;\n let args: unknown[];\n if (plan.params) {\n method = \"transact\";\n args = [\n \"0x\",\n {\n params: feeDefaults(plan.params),\n deliveries: plan.outputs.map((o) => o.delivery),\n funding,\n },\n ];\n } else if (plan.shieldParams) {\n method = \"shield\";\n args = [\n feeDefaults(plan.shieldParams),\n plan.shieldOutputs,\n plan.outputs.map((o) => o.delivery),\n funding,\n ];\n } else if (plan.credit?.creation) {\n method = \"createCredit\";\n args = [\"0x\", plan.credit.creation, plan.credit.deliveries];\n } else if (plan.credit?.draw) {\n method = \"creditDraw\";\n args = [\"0x\", plan.credit.draw, plan.credit.deliveries];\n } else if (plan.credit?.update) {\n method = \"updateCredit\";\n args = [\"0x\", plan.credit.update, plan.credit.deliveries];\n } else if (plan.credit?.revocation) {\n const p = plan.credit.revocation;\n method = \"revokeCredit\";\n args = [\n p.token,\n p.owner,\n p.shard,\n p.slot,\n p.deadline,\n p.feeRecipient ?? \"0x0000000000000000000000000000000000000000\",\n p.feeAmount ?? 0n,\n \"0x\",\n ];\n } else throw new Error(\"unsupported broadcaster operation\");\n const abi = invisiProtocolAbi.filter(\n (item) =>\n item.type === \"function\" &&\n item.name === method &&\n (method !== \"transact\" || item.inputs[1]?.type === \"tuple\")\n );\n return {\n sendable: false as const,\n data: new Interface(abi).encodeFunctionData(method, args) as Hex,\n };\n}\n","import {\n normalizeTransactRequest,\n transactUserPublicInputs,\n ZERO_ADDRESS,\n} from \"@invisi-labs/protocol\";\nimport { WitnessBuilder } from \"@invisi-labs/prover\";\nimport type { Hex } from \"@invisi-labs/protocol/contracts\";\nimport { getAddress } from \"ethers\";\nimport { NoteOutput, resolvedOutputSnapshot } from \"../../notes/NoteOutput\";\nimport type {\n RevokeCreditPreparation,\n CreateCreditPreparation,\n DrawCreditPreparation,\n OperationPlan,\n PreparationRuntime,\n ShieldPreparation,\n UpdateCreditPreparation,\n TransferPreparation,\n} from \"../operation-types\";\nimport {\n positiveAmount,\n positiveOutputAmount,\n Preparation,\n type PreparationFrame,\n} from \"./prepare-common\";\n\n/** Shared preparation engine for managed sessions and explicitly supplied inputs. */\nexport class TransactionPreparation<Result> {\n #intent: import(\"../../broadcaster/broadcaster-preparation\").PreparationIntent | undefined;\n constructor(readonly context: PreparationRuntime<Result>) {\n const complete = context.complete;\n this.context = {\n ...context,\n complete: (plan) => {\n const intent = this.#intent ? structuredClone(this.#intent) : undefined;\n if (intent && (intent.kind === \"transfer\" || intent.kind === \"shield\")) {\n const businessOutputs = plan.outputs.filter((output) => !output.change);\n intent.options.outputs = intent.options.outputs.map((payment, index) =>\n resolvedOutputSnapshot(payment, businessOutputs[index]!)\n );\n }\n return complete({ ...plan, ...(intent ? { intent } : {}) });\n },\n };\n }\n private runtime(tokenAddress: Hex): PreparationRuntime<Result> {\n if (\n getAddress(tokenAddress) !==\n getAddress(this.context.options.protocol.context.tokenAddress)\n )\n throw new Error(\"preparation token mismatch\");\n return this.context;\n }\n private get scope() {\n return this.context.scope;\n }\n async prepareTransfer(options: TransferPreparation): Promise<Result> {\n this.#intent = { kind: \"transfer\", options: structuredClone(options) };\n if (Object.hasOwn(options, \"target\") || Object.hasOwn(options, \"execution\")) {\n throw new Error(\n \"prepareTransfer accepts no target or execution; choose execution in prove()\"\n );\n }\n const copied = structuredClone(options);\n const runtime = this.runtime(copied.tokenAddress);\n if (copied.commitments !== undefined && copied.commitments.length === 0)\n throw new Error(\"empty explicit input selection\");\n const preparation = new Preparation({\n ...runtime,\n ...(copied.commitments !== undefined ? { inputSelection: copied.commitments } : {}),\n });\n const frame = await preparation.frame(copied.deadline);\n if (copied.outputs.length > 190) throw new Error(\"transfer supports at most 190 outputs\");\n let withdrawalAddress: Hex = ZERO_ADDRESS;\n let withdrawalAmount = 0n;\n if (copied.withdrawal !== undefined) {\n withdrawalAddress = getAddress(copied.withdrawal.to) as Hex;\n positiveAmount(copied.withdrawal.amount);\n if (BigInt(withdrawalAddress) === 0n)\n throw new Error(\"withdrawal destination must be nonzero\");\n withdrawalAmount = copied.withdrawal.amount;\n }\n if (copied.outputs.length === 0 && withdrawalAmount === 0n)\n throw new Error(\"transfer requires a private output or public withdrawal\");\n const feeRecipient = copied.fee ? (getAddress(copied.fee.recipient) as Hex) : ZERO_ADDRESS;\n const feeAmount = copied.fee?.amount ?? 0n;\n if (copied.fee) {\n positiveAmount(feeAmount);\n if (BigInt(feeRecipient) === 0n) throw new Error(\"fee recipient must be nonzero\");\n }\n const total = copied.outputs.reduce(\n (sum, output, index) => sum + positiveOutputAmount(output, index),\n withdrawalAmount + feeAmount\n );\n const funding = await preparation.funding(copied.funding, frame);\n return this.funds(\n copied.outputs,\n total,\n withdrawalAddress,\n withdrawalAmount,\n { recipient: feeRecipient, amount: feeAmount },\n frame,\n funding,\n preparation\n );\n }\n\n private async funds(\n payments: readonly NoteOutput[],\n total: bigint,\n withdrawalAddress: `0x${string}`,\n withdrawalAmount: bigint,\n fee: { recipient: Hex; amount: bigint },\n frame: PreparationFrame,\n funding: Pick<OperationPlan, \"funding\" | \"fundingMode\">,\n preparation: Preparation<Result>\n ): Promise<Result> {\n if (total >= 1n << 135n) {\n throw new Error(\"transaction sum exceeds uint135\");\n }\n const { context, block, deadline } = frame;\n const selection = await preparation.selectFunds(\n total - (funding.funding.amount ?? 0n),\n frame\n );\n const outputs = await Promise.all(\n payments.map((payment, index) => preparation.output(payment, context, false, index))\n );\n const change = selection.amount + (funding.funding.amount ?? 0n) - total;\n if (change > 0n) {\n outputs.push(await preparation.change(change, context));\n }\n const params = {\n token: context.tokenAddress,\n sources: selection.sources,\n nullifiers: selection.nullifiers,\n noteCommitments: outputs.map((output) => output.commitment),\n withdrawalAddress,\n withdrawalAmount,\n deadline,\n feeRecipient: fee.recipient,\n feeAmount: fee.amount,\n };\n const deliveries = outputs.map((output) => output.delivery);\n const normalized = normalizeTransactRequest(context, params, deliveries, funding.funding);\n const statement = WitnessBuilder.statement(\n `transact_user_slots${normalized.capacity}`,\n transactUserPublicInputs(context, params, deliveries, funding.funding),\n \"evm\"\n );\n await preparation.assertBlock(frame);\n return preparation.runtime.complete({\n version: 1,\n id: crypto.randomUUID(),\n kind: \"transfer\",\n context,\n scope: this.scope,\n preparedAt: block,\n deadline,\n outputs,\n inputs: selection.inputs,\n ...funding,\n params,\n capacity: normalized.capacity,\n statement,\n });\n }\n\n async prepareShield(options: ShieldPreparation): Promise<Result> {\n this.#intent = { kind: \"shield\", options: structuredClone(options) };\n const copied = structuredClone(options);\n const preparation = new Preparation(this.runtime(copied.tokenAddress));\n const frame = await preparation.frame(copied.deadline);\n const funding = await preparation.funding(copied.funding, frame);\n if (copied.outputs.length < 1 || copied.outputs.length > 10) {\n throw new Error(\"shield requires 1..10 outputs\");\n }\n const outputs = await Promise.all(\n copied.outputs.map((output, index) =>\n preparation.output(output, frame.context, false, index)\n )\n );\n if (\n outputs.reduce((sum, output) => sum + output.amount, 0n) !==\n (funding.funding.amount ?? 0n) - (copied.fee?.amount ?? 0n)\n ) {\n throw new Error(\"shield funding must equal output total\");\n }\n await preparation.assertBlock(frame);\n return preparation.runtime.complete({\n version: 1,\n id: crypto.randomUUID(),\n kind: \"shield\",\n context: frame.context,\n scope: this.scope,\n preparedAt: frame.block,\n deadline: frame.deadline,\n outputs,\n inputs: [],\n ...funding,\n shieldParams: {\n token: frame.context.tokenAddress,\n feeRecipient: copied.fee?.recipient ?? ZERO_ADDRESS,\n feeAmount: copied.fee?.amount ?? 0n,\n noteCommitments: outputs.map((output) => output.commitment),\n deadline: frame.deadline,\n },\n shieldOutputs: outputs.map((output) => ({\n identity: output.identity,\n amount: output.amount,\n })),\n });\n }\n\n async prepareCreateCredit(options: CreateCreditPreparation): Promise<Result> {\n const copied = structuredClone(options);\n this.#intent = { kind: \"create-credit\", options: structuredClone(copied) };\n const { CreditPreparation } = await import(\"../../credit/preparation\");\n return new CreditPreparation(this.runtime(copied.tokenAddress)).create(copied);\n }\n\n async prepareDrawCredit(options: DrawCreditPreparation): Promise<Result> {\n const copied = structuredClone(options);\n this.#intent = { kind: \"draw-credit\", options: structuredClone(copied) };\n const { CreditPreparation } = await import(\"../../credit/preparation\");\n return new CreditPreparation(this.runtime(copied.tokenAddress)).draw(copied);\n }\n\n async prepareUpdateCredit(options: UpdateCreditPreparation): Promise<Result> {\n const copied = structuredClone(options);\n this.#intent = { kind: \"update-credit\", options: structuredClone(copied) };\n const { CreditPreparation } = await import(\"../../credit/preparation\");\n return new CreditPreparation(this.runtime(copied.tokenAddress)).update(copied);\n }\n\n async prepareRevokeCredit(options: RevokeCreditPreparation): Promise<Result> {\n const copied = structuredClone(options);\n this.#intent = { kind: \"revoke-credit\", options: structuredClone(copied) };\n const { CreditPreparation } = await import(\"../../credit/preparation\");\n return new CreditPreparation(this.runtime(copied.tokenAddress)).revoke(copied);\n }\n}\n"],"mappings":"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","names":["statement"]}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkMI4IP4ZDcjs = require('./chunk-MI4IP4ZD.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkHCB7RQ3Scjs = require('./chunk-HCB7RQ3S.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
var _chunk3KTQQZOWcjs = require('./chunk-3KTQQZOW.cjs');
|
|
10
|
+
|
|
11
|
+
// src/broadcaster/provenance-preparation.ts
|
|
12
|
+
var _provenance = require('@invisi-labs/rpc/provenance');
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
var _provenance3 = require('@invisi-labs/protocol/provenance');
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
var _provenancewitness = require('@invisi-labs/prover/provenance-witness');
|
|
25
|
+
function requireProvenanceCapability(plan, runtime) {
|
|
26
|
+
const cap = runtime.options.provenance;
|
|
27
|
+
if (!cap) throw Error("Provenance capability required for private inputs");
|
|
28
|
+
const trust = cap.client.trust;
|
|
29
|
+
if (BigInt(trust.chainId) !== plan.context.chainId || BigInt(trust.protocolAddress) !== BigInt(plan.context.protocolAddress) || cap.manifest.sha256 !== trust.manifestSha256)
|
|
30
|
+
throw Error("Provenance deployment or manifest mismatch");
|
|
31
|
+
}
|
|
32
|
+
async function prepareProvenance(plan, runtime) {
|
|
33
|
+
requireProvenanceCapability(plan, runtime);
|
|
34
|
+
if (!plan.inputs.length) throw Error("No private Note inputs require a Provenance proof");
|
|
35
|
+
const {
|
|
36
|
+
client: source,
|
|
37
|
+
manifest,
|
|
38
|
+
prover,
|
|
39
|
+
maxRootPages = 10,
|
|
40
|
+
maxLeaves = 1e5
|
|
41
|
+
} = runtime.options.provenance;
|
|
42
|
+
if (!Number.isSafeInteger(maxRootPages) || maxRootPages < 1 || maxRootPages > 100 || !Number.isSafeInteger(maxLeaves) || maxLeaves < 1)
|
|
43
|
+
throw Error("Invalid Provenance replay budget");
|
|
44
|
+
if (!plan.params || !plan.capacity || plan.params.nullifiers.length !== plan.inputs.length)
|
|
45
|
+
throw Error("Private transact statement required");
|
|
46
|
+
const trust = source.trust;
|
|
47
|
+
const openings = await Promise.all(
|
|
48
|
+
plan.inputs.map(async (input, i) => {
|
|
49
|
+
const opening = {
|
|
50
|
+
owner: input.note.ownerAddress,
|
|
51
|
+
nonce: input.note.nonce,
|
|
52
|
+
amount: input.note.amount
|
|
53
|
+
};
|
|
54
|
+
const computed = await _provenance3.noteOpening.call(void 0, { ...plan.context, ...opening });
|
|
55
|
+
if (computed.commitment !== BigInt(input.commitment) || computed.nullifier !== BigInt(plan.params.nullifiers[i]))
|
|
56
|
+
throw Error("Prepared Note opening or nullifier mismatch");
|
|
57
|
+
return opening;
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
const digest = _provenance3.operationDigest.call(void 0, {
|
|
61
|
+
...plan.context,
|
|
62
|
+
mainCircuitCapacity: plan.capacity,
|
|
63
|
+
publicInputs: _chunkHCB7RQ3Scjs.statement.call(void 0, plan).expectedPublicInputs
|
|
64
|
+
});
|
|
65
|
+
const status = await source.getStatus();
|
|
66
|
+
const rootId = `${BigInt(trust.chainGeneration)}:${BigInt(String(status.checkpointSequence))}`;
|
|
67
|
+
const latest = await source.getRoot(rootId);
|
|
68
|
+
if (!latest.certificate || latest.allowedForNewProof !== true)
|
|
69
|
+
throw Error("No current recognized root");
|
|
70
|
+
const certificates = /* @__PURE__ */ new Map();
|
|
71
|
+
const matches = /* @__PURE__ */ new Map();
|
|
72
|
+
let remaining = maxLeaves;
|
|
73
|
+
const replay = async (certificate) => {
|
|
74
|
+
_provenance3.assertCertificateTrust.call(void 0, certificate, trust);
|
|
75
|
+
const block = await runtime.reader.getBlock(BigInt(certificate.confirmedBlockNumber));
|
|
76
|
+
if (!block || block.hash.toLowerCase() !== _provenance3.word.call(void 0, certificate.confirmedBlockHash).toLowerCase() || await runtime.reader.getChainId() !== plan.context.chainId)
|
|
77
|
+
throw Error("Provenance checkpoint canonical anchor mismatch");
|
|
78
|
+
const count = Number(BigInt(certificate.leafCount));
|
|
79
|
+
if (!Number.isSafeInteger(count) || count > remaining)
|
|
80
|
+
throw Error("Provenance replay leaf budget exceeded");
|
|
81
|
+
remaining -= count;
|
|
82
|
+
const tree = await source.syncRecognizedTree(
|
|
83
|
+
`${certificate.chainGeneration}:${certificate.rootSequence}`,
|
|
84
|
+
certificate,
|
|
85
|
+
{ maxLeaves: Math.max(1, count) }
|
|
86
|
+
);
|
|
87
|
+
certificates.set(String(certificate.treeId), certificate);
|
|
88
|
+
for (let i = 0; i < plan.inputs.length; i++) {
|
|
89
|
+
if (matches.has(i)) continue;
|
|
90
|
+
const membership = await tree.membershipForCommitment(
|
|
91
|
+
trust,
|
|
92
|
+
plan.inputs[i].commitment
|
|
93
|
+
);
|
|
94
|
+
if (membership) matches.set(i, { certificate, membership });
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
await replay(latest.certificate);
|
|
98
|
+
if (matches.size !== plan.inputs.length) {
|
|
99
|
+
const newest = /* @__PURE__ */ new Map();
|
|
100
|
+
let cursor, complete = false;
|
|
101
|
+
for (let page = 0; page < maxRootPages; page++) {
|
|
102
|
+
const result = await source.getRoots(
|
|
103
|
+
cursor ? { cursor, limit: 200 } : { after: "0", limit: 200 }
|
|
104
|
+
);
|
|
105
|
+
for (const certificate of result.items) {
|
|
106
|
+
const previous = newest.get(String(certificate.treeId));
|
|
107
|
+
if (!previous || BigInt(previous.rootSequence) < BigInt(certificate.rootSequence))
|
|
108
|
+
newest.set(String(certificate.treeId), certificate);
|
|
109
|
+
}
|
|
110
|
+
if (!result.nextCursor) {
|
|
111
|
+
complete = true;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
const next = String(result.nextCursor);
|
|
115
|
+
if (next === cursor) throw Error("Provenance root cursor did not advance");
|
|
116
|
+
cursor = next;
|
|
117
|
+
}
|
|
118
|
+
if (!complete) throw Error("Provenance root replay page budget exceeded");
|
|
119
|
+
for (const certificate of newest.values()) {
|
|
120
|
+
if (certificates.has(String(certificate.treeId))) continue;
|
|
121
|
+
const current = await source.getRoot(
|
|
122
|
+
`${certificate.chainGeneration}:${certificate.rootSequence}`
|
|
123
|
+
);
|
|
124
|
+
if (current.allowedForNewProof !== true) continue;
|
|
125
|
+
await replay(certificate);
|
|
126
|
+
if (matches.size === plan.inputs.length) break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (matches.size !== plan.inputs.length) throw Error("Prepared Note is not recognized");
|
|
130
|
+
const used = [
|
|
131
|
+
...new Map(
|
|
132
|
+
[...matches.values()].map((m) => [String(m.certificate.treeId), m.certificate])
|
|
133
|
+
).values()
|
|
134
|
+
].sort((a, b) => BigInt(a.treeId) < BigInt(b.treeId) ? -1 : 1);
|
|
135
|
+
const inputs = openings.map((opening, i) => {
|
|
136
|
+
const match = matches.get(i);
|
|
137
|
+
return {
|
|
138
|
+
...opening,
|
|
139
|
+
sourceIndex: used.findIndex(
|
|
140
|
+
(c) => BigInt(c.treeId) === BigInt(match.certificate.treeId)
|
|
141
|
+
),
|
|
142
|
+
leafIndex: match.membership.leafIndex,
|
|
143
|
+
path: match.membership.path
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
const capacity = _provenance3.CAPACITIES.find((k) => k >= inputs.length);
|
|
147
|
+
if (!capacity) throw Error("Provenance input capacity exceeded");
|
|
148
|
+
const sidecar = await _provenancewitness.exportSidecar.call(void 0,
|
|
149
|
+
{
|
|
150
|
+
...trust,
|
|
151
|
+
capacity,
|
|
152
|
+
tokenAddress: plan.context.tokenAddress,
|
|
153
|
+
operationDigest: digest,
|
|
154
|
+
inputs,
|
|
155
|
+
sources: used.map((c) => ({ treeId: c.treeId, root: c.root, leafCount: c.leafCount }))
|
|
156
|
+
},
|
|
157
|
+
used,
|
|
158
|
+
trust,
|
|
159
|
+
manifest,
|
|
160
|
+
prover,
|
|
161
|
+
0
|
|
162
|
+
);
|
|
163
|
+
return { operationDigest: digest, sidecars: [sidecar] };
|
|
164
|
+
}
|
|
165
|
+
async function provePreparedProvenance(saved, runtime, capability, reprove = false) {
|
|
166
|
+
if (!saved.call || !saved.proof || saved.plan.kind !== "transfer" || !saved.plan.inputs.length)
|
|
167
|
+
throw Error("Ready transaction with private Note inputs required");
|
|
168
|
+
const provider = runtime.options.prover;
|
|
169
|
+
const active = await _asyncNullishCoalesce(await _asyncNullishCoalesce(capability, async () => ( runtime.options.provenance)), async () => ( (_optionalChain([provider, 'optionalAccess', _ => _.getProvenanceCapability]) ? {
|
|
170
|
+
...await provider.getProvenanceCapability(),
|
|
171
|
+
client: await _asyncNullishCoalesce(runtime.options.provenanceClient, async () => ( await officialProvenance.get(saved.plan.context)))
|
|
172
|
+
} : void 0)));
|
|
173
|
+
if (!active) throw Error("Local Provenance capability required");
|
|
174
|
+
if (saved.provenance && !reprove)
|
|
175
|
+
return _chunkMI4IP4ZDcjs.validateProvenanceProof.call(void 0, structuredClone(saved.provenance), active.client.trust);
|
|
176
|
+
const localRuntime = { ...runtime, options: { ...runtime.options, provenance: active } };
|
|
177
|
+
const evidence = await prepareProvenance(saved.plan, localRuntime);
|
|
178
|
+
const packet = {
|
|
179
|
+
format: "invisi-provenance-submission-v1",
|
|
180
|
+
data: saved.call.data,
|
|
181
|
+
context: {
|
|
182
|
+
chainId: saved.plan.context.chainId.toString(),
|
|
183
|
+
protocolAddress: saved.plan.context.protocolAddress,
|
|
184
|
+
tokenAddress: saved.plan.context.tokenAddress
|
|
185
|
+
},
|
|
186
|
+
mainCircuitCapacity: saved.plan.capacity,
|
|
187
|
+
publicInputs: [..._chunkHCB7RQ3Scjs.statement.call(void 0, saved.plan).expectedPublicInputs],
|
|
188
|
+
...evidence
|
|
189
|
+
};
|
|
190
|
+
return _chunkMI4IP4ZDcjs.validateProvenanceProof.call(void 0, packet, active.client.trust);
|
|
191
|
+
}
|
|
192
|
+
function validateBroadcastEnvelope(saved, client) {
|
|
193
|
+
if (!saved.broadcasterQuote || !saved.broadcasterBinding || !saved.call)
|
|
194
|
+
throw Error("Prepared broadcaster quote and ready call required");
|
|
195
|
+
if (JSON.stringify(saved.broadcasterBinding.configuration) !== JSON.stringify(client.configuration) || saved.broadcasterBinding.intentHash !== _chunk3KTQQZOWcjs.broadcasterRequestHash.call(void 0, saved.call.data))
|
|
196
|
+
throw Error("Prepared broadcaster context changed");
|
|
197
|
+
const context = saved.plan.context;
|
|
198
|
+
if (BigInt(saved.call.to) !== BigInt(context.protocolAddress) || saved.call.value !== 0n || _optionalChain([saved, 'access', _2 => _2.broadcasterQuote, 'access', _3 => _3.context, 'optionalAccess', _4 => _4.chainId]) !== context.chainId || BigInt(saved.broadcasterQuote.context.protocol) !== BigInt(context.protocolAddress))
|
|
199
|
+
throw Error("Prepared broadcaster deployment changed");
|
|
200
|
+
}
|
|
201
|
+
async function validatePreparedBroadcast(saved, client, runtime) {
|
|
202
|
+
validateBroadcastEnvelope(saved, client);
|
|
203
|
+
if (saved.broadcasterQuote.provenanceRequired && saved.plan.inputs.length) {
|
|
204
|
+
const source = saved.provenance;
|
|
205
|
+
if (!source || source.sidecars.length !== 1)
|
|
206
|
+
throw Error("Prepared Provenance evidence required");
|
|
207
|
+
const digest = _provenance3.operationDigest.call(void 0, {
|
|
208
|
+
...saved.plan.context,
|
|
209
|
+
mainCircuitCapacity: saved.plan.capacity,
|
|
210
|
+
publicInputs: _chunkHCB7RQ3Scjs.statement.call(void 0, saved.plan).expectedPublicInputs
|
|
211
|
+
});
|
|
212
|
+
if (source.operationDigest !== digest || source.data !== saved.call.data)
|
|
213
|
+
throw Error("Prepared Provenance statement changed");
|
|
214
|
+
const sidecar = source.sidecars[0];
|
|
215
|
+
const pi = sidecar.proofBundle.publicInputs;
|
|
216
|
+
if (sidecar.operationIndex !== "0" || _provenance3.word.call(void 0, BigInt(pi[7]) << 128n | BigInt(pi[8])) !== digest || BigInt(pi[2]) !== BigInt(saved.plan.context.tokenAddress) || BigInt(pi[6]) !== BigInt(saved.plan.inputs.length) || BigInt(pi[9]) !== await _provenance3.inputDigest.call(void 0, saved.plan.params.nullifiers))
|
|
217
|
+
throw Error("Prepared Provenance evidence binding mismatch");
|
|
218
|
+
if (runtime.options.provenance)
|
|
219
|
+
await _provenance3.validateProofBundle.call(void 0, sidecar.proofBundle, runtime.options.provenance.client.trust);
|
|
220
|
+
} else if (saved.provenance) throw Error("Unexpected Prepared Provenance evidence");
|
|
221
|
+
}
|
|
222
|
+
var officialProvenance = new (0, _provenance.OfficialProvenanceClients)();
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
exports.prepareProvenance = prepareProvenance; exports.provePreparedProvenance = provePreparedProvenance; exports.validateBroadcastEnvelope = validateBroadcastEnvelope; exports.validatePreparedBroadcast = validatePreparedBroadcast;
|
|
230
|
+
//# sourceMappingURL=chunk-J6TZZVAM.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/wx/Workspace/invisi-lab/invisi-sdk-ts/packages/sdk/dist/chunk-J6TZZVAM.cjs","../src/broadcaster/provenance-preparation.ts"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACVA,yDAA0C;AAE1C;AACI;AACA;AACA;AACA;AACA;AACA;AACA;AAAA,+DAIG;AACP;AACI;AAAA,2EAGG;AAiBP,SAAS,2BAAA,CAA4B,IAAA,EAAqB,OAAA,EAA6B;AACnF,EAAA,MAAM,IAAA,EAAM,OAAA,CAAQ,OAAA,CAAQ,UAAA;AAC5B,EAAA,GAAA,CAAI,CAAC,GAAA,EAAK,MAAM,KAAA,CAAM,mDAAmD,CAAA;AACzE,EAAA,MAAM,MAAA,EAAQ,GAAA,CAAI,MAAA,CAAO,KAAA;AACzB,EAAA,GAAA,CACI,MAAA,CAAO,KAAA,CAAM,OAAO,EAAA,IAAM,IAAA,CAAK,OAAA,CAAQ,QAAA,GACvC,MAAA,CAAO,KAAA,CAAM,eAAe,EAAA,IAAM,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,eAAe,EAAA,GACrE,GAAA,CAAI,QAAA,CAAS,OAAA,IAAW,KAAA,CAAM,cAAA;AAE9B,IAAA,MAAM,KAAA,CAAM,4CAA4C,CAAA;AAChE;AACA,MAAA,SAAsB,iBAAA,CAClB,IAAA,EACA,OAAA,EAC8D;AAC9D,EAAA,2BAAA,CAA4B,IAAA,EAAM,OAAO,CAAA;AACzC,EAAA,GAAA,CAAI,CAAC,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,MAAM,KAAA,CAAM,mDAAmD,CAAA;AACxF,EAAA,MAAM;AAAA,IACF,MAAA,EAAQ,MAAA;AAAA,IACR,QAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA,EAAe,EAAA;AAAA,IACf,UAAA,EAAY;AAAA,EAChB,EAAA,EAAI,OAAA,CAAS,OAAA,CAAQ,UAAA;AACrB,EAAA,GAAA,CACI,CAAC,MAAA,CAAO,aAAA,CAAc,YAAY,EAAA,GAClC,aAAA,EAAe,EAAA,GACf,aAAA,EAAe,IAAA,GACf,CAAC,MAAA,CAAO,aAAA,CAAc,SAAS,EAAA,GAC/B,UAAA,EAAY,CAAA;AAEZ,IAAA,MAAM,KAAA,CAAM,kCAAkC,CAAA;AAClD,EAAA,GAAA,CAAI,CAAC,IAAA,CAAK,OAAA,GAAU,CAAC,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,UAAA,CAAW,OAAA,IAAW,IAAA,CAAK,MAAA,CAAO,MAAA;AAChF,IAAA,MAAM,KAAA,CAAM,qCAAqC,CAAA;AACrD,EAAA,MAAM,MAAA,EAAQ,MAAA,CAAO,KAAA;AACrB,EAAA,MAAM,SAAA,EAAW,MAAM,OAAA,CAAQ,GAAA;AAAA,IAC3B,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAA,CAAO,KAAA,EAAO,CAAA,EAAA,GAAM;AAChC,MAAA,MAAM,QAAA,EAAU;AAAA,QACZ,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,YAAA;AAAA,QAClB,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,KAAA;AAAA,QAClB,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK;AAAA,MACvB,CAAA;AACA,MAAA,MAAM,SAAA,EAAW,MAAM,sCAAA,EAAc,GAAG,IAAA,CAAK,OAAA,EAAS,GAAG,QAAQ,CAAC,CAAA;AAClE,MAAA,GAAA,CACI,QAAA,CAAS,WAAA,IAAe,MAAA,CAAO,KAAA,CAAM,UAAU,EAAA,GAC/C,QAAA,CAAS,UAAA,IAAc,MAAA,CAAO,IAAA,CAAK,MAAA,CAAQ,UAAA,CAAW,CAAC,CAAE,CAAA;AAEzD,QAAA,MAAM,KAAA,CAAM,6CAA6C,CAAA;AAC7D,MAAA,OAAO,OAAA;AAAA,IACX,CAAC;AAAA,EACL,CAAA;AACA,EAAA,MAAM,OAAA,EAAS,0CAAA;AAAgB,IAC3B,GAAG,IAAA,CAAK,OAAA;AAAA,IACR,mBAAA,EAAqB,IAAA,CAAK,QAAA;AAAA,IAC1B,YAAA,EAAc,yCAAA,IAAc,CAAA,CAAE;AAAA,EAClC,CAAC,CAAA;AACD,EAAA,MAAM,OAAA,EAAS,MAAM,MAAA,CAAO,SAAA,CAAU,CAAA;AACtC,EAAA,MAAM,OAAA,EAAS,CAAA,EAAA;AACA,EAAA;AACH,EAAA;AACI,IAAA;AACV,EAAA;AACU,EAAA;AAIA,EAAA;AACD,EAAA;AACX,IAAA;AACc,IAAA;AAGV,IAAA;AAGY,MAAA;AACF,IAAA;AACF,IAAA;AACI,MAAA;AACH,IAAA;AACA,IAAA;AACN,MAAA;AACH,MAAA;AACE,MAAA;AACN,IAAA;AACa,IAAA;AACA,IAAA;AACG,MAAA;AACN,MAAA;AACF,QAAA;AACK,QAAA;AACT,MAAA;AACI,MAAA;AACR,IAAA;AACJ,EAAA;AACa,EAAA;AACD,EAAA;AACF,IAAA;AAEF,IAAA;AACK,IAAA;AACC,MAAA;AACO,QAAA;AACb,MAAA;AACW,MAAA;AACD,QAAA;AACD,QAAA;AACM,UAAA;AACf,MAAA;AACY,MAAA;AACR,QAAA;AACA,QAAA;AACJ,MAAA;AACM,MAAA;AACF,MAAA;AACK,MAAA;AACb,IAAA;AACe,IAAA;AACJ,IAAA;AACH,MAAA;AACE,MAAA;AACC,QAAA;AACP,MAAA;AACY,MAAA;AACN,MAAA;AACM,MAAA;AAChB,IAAA;AACJ,EAAA;AACY,EAAA;AACC,EAAA;AACF,IAAA;AACS,MAAA;AACP,IAAA;AACF,EAAA;AACoB,EAAA;AACb,IAAA;AACP,IAAA;AACA,MAAA;AACH,MAAA;AACW,QAAA;AACX,MAAA;AACW,MAAA;AACC,MAAA;AAChB,IAAA;AACH,EAAA;AACK,EAAA;AACS,EAAA;AACC,EAAA;AACZ,IAAA;AACO,MAAA;AACH,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACS,MAAA;AACb,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACJ,EAAA;AACS,EAAA;AACb;AACsB;AAMP,EAAA;AACK,IAAA;AACV,EAAA;AAGF,EAAA;AAIoB,IAAA;AAEN,IAAA;AAGR,EAAA;AACG,EAAA;AACH,EAAA;AACC,IAAA;AACL,EAAA;AACA,EAAA;AAC0B,EAAA;AACpB,IAAA;AACI,IAAA;AACH,IAAA;AACI,MAAA;AACT,MAAA;AACA,MAAA;AACJ,IAAA;AACA,IAAA;AACc,IAAA;AACX,IAAA;AACP,EAAA;AACO,EAAA;AACX;AACgB;AACD,EAAA;AACK,IAAA;AAEP,EAAA;AAIO,IAAA;AACA,EAAA;AAEL,EAAA;AAKK,IAAA;AACpB;AACsB;AAKlB,EAAA;AACU,EAAA;AACA,IAAA;AACD,IAAA;AACW,MAAA;AACV,IAAA;AACO,MAAA;AACT,MAAA;AACA,MAAA;AACH,IAAA;AACU,IAAA;AACK,MAAA;AACV,IAAA;AACK,IAAA;AAEC,IAAA;AAMI,MAAA;AACJ,IAAA;AACF,MAAA;AACH,EAAA;AACf;AAEM;ADnEY;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/wx/Workspace/invisi-lab/invisi-sdk-ts/packages/sdk/dist/chunk-J6TZZVAM.cjs","sourcesContent":[null,"import { OfficialProvenanceClients } from \"@invisi-labs/rpc/provenance\";\nimport { validateProvenanceProof, type ProvenanceProof } from \"../provenance/proof-record\";\nimport {\n CAPACITIES,\n noteOpening,\n operationDigest,\n word,\n assertCertificateTrust,\n validateProofBundle,\n inputDigest,\n type ManifestIdentity,\n type ProofSidecar,\n type RootCertificate,\n} from \"@invisi-labs/protocol/provenance\";\nimport {\n exportSidecar,\n type OfflineProver,\n type WitnessInput,\n} from \"@invisi-labs/prover/provenance-witness\";\nimport { type ProvenanceClient } from \"@invisi-labs/rpc/provenance\";\nimport type {\n OperationPlan,\n TransactionRuntime,\n SavedOperation,\n} from \"../transactions/operation-types\";\nimport { statement } from \"../transactions/signing/statement\";\nimport { broadcasterRequestHash, type BroadcasterClient } from \"./index\";\n\nexport interface PreparedProvenanceCapability {\n client: ProvenanceClient;\n manifest: ManifestIdentity;\n prover: OfflineProver;\n maxRootPages?: number;\n maxLeaves?: number;\n}\nfunction requireProvenanceCapability(plan: OperationPlan, runtime: TransactionRuntime) {\n const cap = runtime.options.provenance;\n if (!cap) throw Error(\"Provenance capability required for private inputs\");\n const trust = cap.client.trust;\n if (\n BigInt(trust.chainId) !== plan.context.chainId ||\n BigInt(trust.protocolAddress) !== BigInt(plan.context.protocolAddress) ||\n cap.manifest.sha256 !== trust.manifestSha256\n )\n throw Error(\"Provenance deployment or manifest mismatch\");\n}\nexport async function prepareProvenance(\n plan: OperationPlan,\n runtime: TransactionRuntime\n): Promise<{ operationDigest: string; sidecars: ProofSidecar[] }> {\n requireProvenanceCapability(plan, runtime);\n if (!plan.inputs.length) throw Error(\"No private Note inputs require a Provenance proof\");\n const {\n client: source,\n manifest,\n prover,\n maxRootPages = 10,\n maxLeaves = 100000,\n } = runtime!.options.provenance!;\n if (\n !Number.isSafeInteger(maxRootPages) ||\n maxRootPages < 1 ||\n maxRootPages > 100 ||\n !Number.isSafeInteger(maxLeaves) ||\n maxLeaves < 1\n )\n throw Error(\"Invalid Provenance replay budget\");\n if (!plan.params || !plan.capacity || plan.params.nullifiers.length !== plan.inputs.length)\n throw Error(\"Private transact statement required\");\n const trust = source.trust;\n const openings = await Promise.all(\n plan.inputs.map(async (input, i) => {\n const opening = {\n owner: input.note.ownerAddress,\n nonce: input.note.nonce,\n amount: input.note.amount,\n };\n const computed = await noteOpening({ ...plan.context, ...opening });\n if (\n computed.commitment !== BigInt(input.commitment) ||\n computed.nullifier !== BigInt(plan.params!.nullifiers[i]!)\n )\n throw Error(\"Prepared Note opening or nullifier mismatch\");\n return opening;\n })\n );\n const digest = operationDigest({\n ...plan.context,\n mainCircuitCapacity: plan.capacity,\n publicInputs: statement(plan).expectedPublicInputs,\n });\n const status = await source.getStatus();\n const rootId = `${BigInt(trust.chainGeneration)}:${BigInt(String(status.checkpointSequence))}`;\n const latest = await source.getRoot(rootId);\n if (!latest.certificate || latest.allowedForNewProof !== true)\n throw Error(\"No current recognized root\");\n const certificates = new Map<string, RootCertificate>();\n const matches = new Map<\n number,\n { certificate: RootCertificate; membership: { leafIndex: number; path: bigint[] } }\n >();\n let remaining = maxLeaves;\n const replay = async (certificate: RootCertificate) => {\n assertCertificateTrust(certificate, trust);\n const block = await runtime!.reader.getBlock(BigInt(certificate.confirmedBlockNumber));\n if (\n !block ||\n block.hash.toLowerCase() !== word(certificate.confirmedBlockHash).toLowerCase() ||\n (await runtime!.reader.getChainId()) !== plan.context.chainId\n )\n throw Error(\"Provenance checkpoint canonical anchor mismatch\");\n const count = Number(BigInt(certificate.leafCount));\n if (!Number.isSafeInteger(count) || count > remaining)\n throw Error(\"Provenance replay leaf budget exceeded\");\n remaining -= count;\n const tree = await source.syncRecognizedTree(\n `${certificate.chainGeneration}:${certificate.rootSequence}`,\n certificate,\n { maxLeaves: Math.max(1, count) }\n );\n certificates.set(String(certificate.treeId), certificate);\n for (let i = 0; i < plan.inputs.length; i++) {\n if (matches.has(i)) continue;\n const membership = await tree.membershipForCommitment(\n trust,\n plan.inputs[i]!.commitment\n );\n if (membership) matches.set(i, { certificate, membership });\n }\n };\n await replay(latest.certificate as RootCertificate);\n if (matches.size !== plan.inputs.length) {\n const newest = new Map<string, RootCertificate>();\n let cursor: string | undefined,\n complete = false;\n for (let page = 0; page < maxRootPages; page++) {\n const result = await source.getRoots(\n cursor ? { cursor, limit: 200 } : { after: \"0\", limit: 200 }\n );\n for (const certificate of result.items as RootCertificate[]) {\n const previous = newest.get(String(certificate.treeId));\n if (!previous || BigInt(previous.rootSequence) < BigInt(certificate.rootSequence))\n newest.set(String(certificate.treeId), certificate);\n }\n if (!result.nextCursor) {\n complete = true;\n break;\n }\n const next = String(result.nextCursor);\n if (next === cursor) throw Error(\"Provenance root cursor did not advance\");\n cursor = next;\n }\n if (!complete) throw Error(\"Provenance root replay page budget exceeded\");\n for (const certificate of newest.values()) {\n if (certificates.has(String(certificate.treeId))) continue;\n const current = await source.getRoot(\n `${certificate.chainGeneration}:${certificate.rootSequence}`\n );\n if (current.allowedForNewProof !== true) continue;\n await replay(certificate);\n if (matches.size === plan.inputs.length) break;\n }\n }\n if (matches.size !== plan.inputs.length) throw Error(\"Prepared Note is not recognized\");\n const used = [\n ...new Map(\n [...matches.values()].map((m) => [String(m.certificate.treeId), m.certificate])\n ).values(),\n ].sort((a, b) => (BigInt(a.treeId) < BigInt(b.treeId) ? -1 : 1));\n const inputs: WitnessInput[] = openings.map((opening, i) => {\n const match = matches.get(i)!;\n return {\n ...opening,\n sourceIndex: used.findIndex(\n (c) => BigInt(c.treeId) === BigInt(match.certificate.treeId)\n ),\n leafIndex: match.membership.leafIndex,\n path: match.membership.path,\n };\n });\n const capacity = CAPACITIES.find((k) => k >= inputs.length);\n if (!capacity) throw Error(\"Provenance input capacity exceeded\");\n const sidecar = await exportSidecar(\n {\n ...trust,\n capacity,\n tokenAddress: plan.context.tokenAddress,\n operationDigest: digest,\n inputs,\n sources: used.map((c) => ({ treeId: c.treeId, root: c.root, leafCount: c.leafCount })),\n },\n used,\n trust,\n manifest,\n prover,\n 0\n );\n return { operationDigest: digest, sidecars: [sidecar] };\n}\nexport async function provePreparedProvenance(\n saved: SavedOperation,\n runtime: TransactionRuntime,\n capability?: PreparedProvenanceCapability,\n reprove = false\n): Promise<ProvenanceProof> {\n if (!saved.call || !saved.proof || saved.plan.kind !== \"transfer\" || !saved.plan.inputs.length)\n throw Error(\"Ready transaction with private Note inputs required\");\n const provider = runtime.options.prover as typeof runtime.options.prover &\n Partial<import(\"@invisi-labs/prover/provenance-witness\").ProvenanceProvider>;\n const active =\n capability ??\n runtime.options.provenance ??\n (provider?.getProvenanceCapability\n ? {\n ...(await provider.getProvenanceCapability()),\n client:\n runtime.options.provenanceClient ??\n (await officialProvenance.get(saved.plan.context)),\n }\n : undefined);\n if (!active) throw Error(\"Local Provenance capability required\");\n if (saved.provenance && !reprove)\n return validateProvenanceProof(structuredClone(saved.provenance), active.client.trust);\n const localRuntime = { ...runtime, options: { ...runtime.options, provenance: active } };\n const evidence = await prepareProvenance(saved.plan, localRuntime);\n const packet: ProvenanceProof = {\n format: \"invisi-provenance-submission-v1\",\n data: saved.call.data,\n context: {\n chainId: saved.plan.context.chainId.toString(),\n protocolAddress: saved.plan.context.protocolAddress,\n tokenAddress: saved.plan.context.tokenAddress,\n },\n mainCircuitCapacity: saved.plan.capacity!,\n publicInputs: [...statement(saved.plan).expectedPublicInputs],\n ...evidence,\n };\n return validateProvenanceProof(packet, active.client.trust);\n}\nexport function validateBroadcastEnvelope(saved: SavedOperation, client: BroadcasterClient) {\n if (!saved.broadcasterQuote || !saved.broadcasterBinding || !saved.call)\n throw Error(\"Prepared broadcaster quote and ready call required\");\n if (\n JSON.stringify(saved.broadcasterBinding.configuration) !==\n JSON.stringify(client.configuration) ||\n saved.broadcasterBinding.intentHash !== broadcasterRequestHash(saved.call.data)\n )\n throw Error(\"Prepared broadcaster context changed\");\n const context = saved.plan.context;\n if (\n BigInt(saved.call.to) !== BigInt(context.protocolAddress) ||\n saved.call.value !== 0n ||\n saved.broadcasterQuote.context?.chainId !== context.chainId ||\n BigInt(saved.broadcasterQuote.context.protocol) !== BigInt(context.protocolAddress)\n )\n throw Error(\"Prepared broadcaster deployment changed\");\n}\nexport async function validatePreparedBroadcast(\n saved: SavedOperation,\n client: BroadcasterClient,\n runtime: TransactionRuntime\n) {\n validateBroadcastEnvelope(saved, client);\n if (saved.broadcasterQuote!.provenanceRequired && saved.plan.inputs.length) {\n const source = saved.provenance;\n if (!source || source.sidecars.length !== 1)\n throw Error(\"Prepared Provenance evidence required\");\n const digest = operationDigest({\n ...saved.plan.context,\n mainCircuitCapacity: saved.plan.capacity!,\n publicInputs: statement(saved.plan).expectedPublicInputs,\n });\n if (source.operationDigest !== digest || source.data !== saved.call!.data)\n throw Error(\"Prepared Provenance statement changed\");\n const sidecar = source.sidecars[0]!;\n const pi = sidecar.proofBundle.publicInputs;\n if (\n sidecar.operationIndex !== \"0\" ||\n word((BigInt(pi[7]!) << 128n) | BigInt(pi[8]!)) !== digest ||\n BigInt(pi[2]!) !== BigInt(saved.plan.context.tokenAddress) ||\n BigInt(pi[6]!) !== BigInt(saved.plan.inputs.length) ||\n BigInt(pi[9]!) !== (await inputDigest(saved.plan.params!.nullifiers))\n )\n throw Error(\"Prepared Provenance evidence binding mismatch\");\n if (runtime.options.provenance)\n await validateProofBundle(sidecar.proofBundle, runtime.options.provenance.client.trust);\n } else if (saved.provenance) throw Error(\"Unexpected Prepared Provenance evidence\");\n}\n\nconst officialProvenance = new OfficialProvenanceClients();\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } async function _asyncOptionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/integrations/ethers.ts
|
|
2
|
-
var _address = require('@invisi-labs/
|
|
2
|
+
var _address = require('@invisi-labs/primitives/address');
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
@@ -112,6 +112,29 @@ var EthersChainReader = class {
|
|
|
112
112
|
await new (0, _ethers.Contract)(instance, _contracts.invisiProtocolAbi, this.client).getFunction("factory")()
|
|
113
113
|
);
|
|
114
114
|
}
|
|
115
|
+
async getCreditAllocation(context, owner, token, block) {
|
|
116
|
+
const result = await this.read(
|
|
117
|
+
context,
|
|
118
|
+
context.protocolAddress,
|
|
119
|
+
_contracts.invisiProtocolAbi,
|
|
120
|
+
"creditAllocation",
|
|
121
|
+
[owner, token],
|
|
122
|
+
block
|
|
123
|
+
);
|
|
124
|
+
return { shard: BigInt(result[0]), slot: Number(result[1]) };
|
|
125
|
+
}
|
|
126
|
+
async getCreditRevocationBitmap(context, owner, token, shard, wordIndex, block) {
|
|
127
|
+
return BigInt(
|
|
128
|
+
await this.read(
|
|
129
|
+
context,
|
|
130
|
+
context.protocolAddress,
|
|
131
|
+
_contracts.invisiProtocolAbi,
|
|
132
|
+
"creditRevocationBitmap",
|
|
133
|
+
[owner, token, shard, wordIndex],
|
|
134
|
+
block
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
}
|
|
115
138
|
async getLatestBlockNumber() {
|
|
116
139
|
return BigInt(await this.client.getBlockNumber());
|
|
117
140
|
}
|
|
@@ -371,4 +394,4 @@ var EthersFundingVerifier = class {
|
|
|
371
394
|
|
|
372
395
|
|
|
373
396
|
exports.EthersChainReader = EthersChainReader; exports.EthersAddressResolver = EthersAddressResolver; exports.EthersFundingSigner = EthersFundingSigner; exports.EthersFundingVerifier = EthersFundingVerifier;
|
|
374
|
-
//# sourceMappingURL=chunk-
|
|
397
|
+
//# sourceMappingURL=chunk-LOR6PYH5.cjs.map
|