@invisi-labs/protocol 1.1.5 → 1.1.6
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/dist/{chunk-47SC3EAI.js → chunk-BYJ4LXCJ.js} +389 -9
- package/dist/chunk-BYJ4LXCJ.js.map +1 -0
- package/dist/contracts.cjs +389 -8
- package/dist/contracts.cjs.map +1 -1
- package/dist/contracts.d.cts +134 -3
- package/dist/contracts.d.ts +134 -3
- package/dist/contracts.js +3 -1
- package/dist/index.cjs +552 -187
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -11
- package/dist/index.d.ts +24 -11
- package/dist/index.js +296 -142
- package/dist/index.js.map +1 -1
- package/dist/{types-BCTQjKzw.d.cts → types-BmUlasOg.d.cts} +179 -7
- package/dist/{types-BCTQjKzw.d.ts → types-BmUlasOg.d.ts} +179 -7
- package/package.json +4 -4
- package/dist/chunk-47SC3EAI.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
invisiAddressRegistryAbi,
|
|
3
3
|
invisiFactoryAbi,
|
|
4
4
|
invisiProtocolAbi
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BYJ4LXCJ.js";
|
|
6
6
|
|
|
7
7
|
// src/AddressRegistry.ts
|
|
8
8
|
import { getAddress as getAddress2, keccak256 } from "ethers";
|
|
@@ -38,10 +38,10 @@ function hexBytes(value, length) {
|
|
|
38
38
|
throw new Error(`Expected ${length} hexadecimal bytes`);
|
|
39
39
|
return getBytes(value);
|
|
40
40
|
}
|
|
41
|
-
function normalizeKeys(
|
|
41
|
+
function normalizeKeys(ownerAddress, keys) {
|
|
42
42
|
const decoded = decodeAddress(
|
|
43
43
|
ReceivingAddress.from({
|
|
44
|
-
|
|
44
|
+
ownerAddress,
|
|
45
45
|
viewingPublicKey: hexBytes(keys.viewingPublicKey, 33),
|
|
46
46
|
clueKey: hexBytes(keys.clueKey, 32)
|
|
47
47
|
}).toString()
|
|
@@ -56,14 +56,14 @@ function normalize(context, registration, options) {
|
|
|
56
56
|
uint64(context.chainId, "chainId");
|
|
57
57
|
const registryAddress = getAddress(context.registryAddress);
|
|
58
58
|
if (BigInt(registryAddress) === 0n) throw new Error("Registry address must be nonzero");
|
|
59
|
-
if (!/^0x(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/.test(registration.
|
|
59
|
+
if (!/^0x(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/.test(registration.ownerAddress))
|
|
60
60
|
throw new Error("Wallet identity must be an EVM owner or padded bytes32");
|
|
61
|
-
const
|
|
61
|
+
const ownerAddress = decodeAddress(
|
|
62
62
|
ReceivingAddress.fromIdentity(
|
|
63
|
-
toBeHex(BigInt(registration.
|
|
63
|
+
toBeHex(BigInt(registration.ownerAddress), 20)
|
|
64
64
|
).toString()
|
|
65
|
-
).
|
|
66
|
-
const keys = normalizeKeys(
|
|
65
|
+
).ownerAddress;
|
|
66
|
+
const keys = normalizeKeys(ownerAddress, registration.keys);
|
|
67
67
|
const nonce = uint64(registration.nonce, "nonce"), deadline = uint64(registration.deadline, "deadline");
|
|
68
68
|
if (nonce === MAX_NONCE) throw new Error("Registry nonce exhausted");
|
|
69
69
|
if (options.update !== void 0 && typeof options.update !== "boolean")
|
|
@@ -74,7 +74,7 @@ function normalize(context, registration, options) {
|
|
|
74
74
|
throw new Error("Registry nonce mismatch");
|
|
75
75
|
if (context.now !== void 0 && deadline < uint64(context.now, "now"))
|
|
76
76
|
throw new Error("Registration expired");
|
|
77
|
-
return { registryAddress, registration: {
|
|
77
|
+
return { registryAddress, registration: { ownerAddress, keys, nonce, deadline } };
|
|
78
78
|
}
|
|
79
79
|
function registrationTypedData(context, registration, options = {}) {
|
|
80
80
|
const { registryAddress, registration: r } = normalize(context, registration, options);
|
|
@@ -97,7 +97,7 @@ function registrationTypedData(context, registration, options = {}) {
|
|
|
97
97
|
]
|
|
98
98
|
},
|
|
99
99
|
message: {
|
|
100
|
-
walletIdentity: toBeHex(BigInt(r.
|
|
100
|
+
walletIdentity: toBeHex(BigInt(r.ownerAddress), 32),
|
|
101
101
|
...r.keys,
|
|
102
102
|
nonce: r.nonce,
|
|
103
103
|
deadline: r.deadline
|
|
@@ -119,8 +119,11 @@ function buildRegistrationCalldata(context, registration, signature, options = {
|
|
|
119
119
|
options.update ? "updateKeys" : "registerKeys",
|
|
120
120
|
[
|
|
121
121
|
{
|
|
122
|
-
|
|
123
|
-
walletIdentity: toBeHex(BigInt(normalized.registration.
|
|
122
|
+
// The registry wire schema retains its deployed EIP-712/ABI field name.
|
|
123
|
+
walletIdentity: toBeHex(BigInt(normalized.registration.ownerAddress), 32),
|
|
124
|
+
keys: normalized.registration.keys,
|
|
125
|
+
nonce: normalized.registration.nonce,
|
|
126
|
+
deadline: normalized.registration.deadline
|
|
124
127
|
},
|
|
125
128
|
signature
|
|
126
129
|
]
|
|
@@ -130,10 +133,10 @@ function buildRegistrationCalldata(context, registration, signature, options = {
|
|
|
130
133
|
function createRegistryReceivingKeyLookup(client, registryAddress) {
|
|
131
134
|
const address = getAddress(registryAddress);
|
|
132
135
|
if (BigInt(address) === 0n) throw new Error("Registry address must be nonzero");
|
|
133
|
-
return async (
|
|
136
|
+
return async (ownerAddress) => {
|
|
134
137
|
const identity = decodeAddress(
|
|
135
|
-
ReceivingAddress.fromIdentity(
|
|
136
|
-
).
|
|
138
|
+
ReceivingAddress.fromIdentity(ownerAddress).toString()
|
|
139
|
+
).ownerAddress;
|
|
137
140
|
const [keys, nonce] = await new Contract(
|
|
138
141
|
address,
|
|
139
142
|
invisiAddressRegistryAbi,
|
|
@@ -181,7 +184,7 @@ var RegistrationOperation = class _RegistrationOperation {
|
|
|
181
184
|
const context = { ...registry.context, now: block.timestamp };
|
|
182
185
|
const nonce = await runtime.reader.getRegistryNonce(
|
|
183
186
|
context,
|
|
184
|
-
runtime.wallet.
|
|
187
|
+
runtime.wallet.ownerAddress,
|
|
185
188
|
block
|
|
186
189
|
);
|
|
187
190
|
check(
|
|
@@ -195,7 +198,7 @@ var RegistrationOperation = class _RegistrationOperation {
|
|
|
195
198
|
const address = ReceivingAddress2.parse(await registry.resolve(runtime.wallet.getAddress()));
|
|
196
199
|
const keys = address.getReceivingKeys();
|
|
197
200
|
const registration = {
|
|
198
|
-
|
|
201
|
+
ownerAddress: runtime.wallet.ownerAddress,
|
|
199
202
|
keys: {
|
|
200
203
|
viewingPublicKey: hexlify2(keys.viewingPublicKey),
|
|
201
204
|
clueKey: hexlify2(keys.clueKey)
|
|
@@ -247,7 +250,7 @@ var RegistrationOperation = class _RegistrationOperation {
|
|
|
247
250
|
"registry signature must be nonempty hexadecimal bytes"
|
|
248
251
|
);
|
|
249
252
|
const p = this.#plan;
|
|
250
|
-
const owner = p.registration.
|
|
253
|
+
const owner = p.registration.ownerAddress;
|
|
251
254
|
let valid = false;
|
|
252
255
|
try {
|
|
253
256
|
const bytes = getBytes2(signature);
|
|
@@ -321,7 +324,7 @@ var RegistrationOperation = class _RegistrationOperation {
|
|
|
321
324
|
check(
|
|
322
325
|
await this.#runtime.reader.getRegistryNonce(
|
|
323
326
|
p.context,
|
|
324
|
-
p.registration.
|
|
327
|
+
p.registration.ownerAddress,
|
|
325
328
|
block
|
|
326
329
|
) === p.registration.nonce,
|
|
327
330
|
"registry nonce changed; prepare again"
|
|
@@ -372,7 +375,7 @@ var RegistrationOperation = class _RegistrationOperation {
|
|
|
372
375
|
const transaction = await reader.getTransaction(hash);
|
|
373
376
|
const call = this.call();
|
|
374
377
|
check(
|
|
375
|
-
transaction && transaction.transactionHash === hash && transaction.to.toLowerCase() === call.to.toLowerCase() && transaction.data.toLowerCase() === call.data.toLowerCase() && transaction.value === 0n && (this.#signature !== "0x" || BigInt(transaction.from) === BigInt(p.registration.
|
|
378
|
+
transaction && transaction.transactionHash === hash && transaction.to.toLowerCase() === call.to.toLowerCase() && transaction.data.toLowerCase() === call.data.toLowerCase() && transaction.value === 0n && (this.#signature !== "0x" || BigInt(transaction.from) === BigInt(p.registration.ownerAddress)),
|
|
376
379
|
"registry transaction differs from frozen request"
|
|
377
380
|
);
|
|
378
381
|
check(
|
|
@@ -394,7 +397,7 @@ var RegistrationOperation = class _RegistrationOperation {
|
|
|
394
397
|
topics: log.topics
|
|
395
398
|
})
|
|
396
399
|
);
|
|
397
|
-
return event.eventName === "ReceivingKeysSet" && BigInt(event.args.walletIdentity) === BigInt(p.registration.
|
|
400
|
+
return event.eventName === "ReceivingKeysSet" && BigInt(event.args.walletIdentity) === BigInt(p.registration.ownerAddress) && event.args.viewingPublicKey.toLowerCase() === p.registration.keys.viewingPublicKey.toLowerCase() && event.args.clueKey.toLowerCase() === p.registration.keys.clueKey.toLowerCase() && event.args.nextNonce === p.registration.nonce + 1n;
|
|
398
401
|
} catch {
|
|
399
402
|
return false;
|
|
400
403
|
}
|
|
@@ -417,7 +420,7 @@ var RegistrationOperation = class _RegistrationOperation {
|
|
|
417
420
|
}
|
|
418
421
|
}
|
|
419
422
|
const head = await reader.getBlock(await reader.getLatestBlockNumber());
|
|
420
|
-
const nonce = await reader.getRegistryNonce(p.context, p.registration.
|
|
423
|
+
const nonce = await reader.getRegistryNonce(p.context, p.registration.ownerAddress, head);
|
|
421
424
|
check(
|
|
422
425
|
(await reader.getBlock(head.number)).hash === head.hash,
|
|
423
426
|
"canonical registry block changed during reconciliation"
|
|
@@ -496,17 +499,8 @@ var AddressRegistry = class {
|
|
|
496
499
|
}
|
|
497
500
|
};
|
|
498
501
|
|
|
499
|
-
// src/
|
|
500
|
-
import {
|
|
501
|
-
AbiCoder as AbiCoder2,
|
|
502
|
-
dataLength as dataLength2,
|
|
503
|
-
getAddress as getAddress4,
|
|
504
|
-
Interface as Interface3,
|
|
505
|
-
isHexString as isHexString3,
|
|
506
|
-
keccak256 as keccak2563,
|
|
507
|
-
ParamType as ParamType2
|
|
508
|
-
} from "ethers";
|
|
509
|
-
import { computeWalletAuthorizationDigest, walletAuthorizationTypedData } from "@invisi-labs/core";
|
|
502
|
+
// src/fee.ts
|
|
503
|
+
import { getAddress as getAddress4 } from "ethers";
|
|
510
504
|
|
|
511
505
|
// src/validation.ts
|
|
512
506
|
import { MAX_CIPHERTEXT_BYTES } from "@invisi-labs/core";
|
|
@@ -611,6 +605,8 @@ function normalizeOpaqueDelivery(value, options = {}) {
|
|
|
611
605
|
throw new Error("absent output requires an empty delivery");
|
|
612
606
|
return { ciphertext: "0x", clue: "0x" };
|
|
613
607
|
}
|
|
608
|
+
if (options.allowEmpty && value.ciphertext === "0x" && value.clue === "0x")
|
|
609
|
+
return { ciphertext: "0x", clue: "0x" };
|
|
614
610
|
const ciphertext = envelope(value.ciphertext, 1, void 0, MAX_CIPHERTEXT_BYTES);
|
|
615
611
|
const clue = envelope(value.clue, 68);
|
|
616
612
|
if (clue.slice(130, 132).toLowerCase() !== "18") throw new Error("clue precision must be 24");
|
|
@@ -669,9 +665,28 @@ var fundingFields = [
|
|
|
669
665
|
{ name: "deadline", type: "uint256" }
|
|
670
666
|
];
|
|
671
667
|
|
|
668
|
+
// src/fee.ts
|
|
669
|
+
function normalizeFee(p) {
|
|
670
|
+
const feeRecipient = getAddress4(p.feeRecipient ?? ZERO_ADDRESS);
|
|
671
|
+
const feeAmount = uint(p.feeAmount ?? 0n, 128, "feeAmount");
|
|
672
|
+
if (BigInt(feeRecipient) === 0n !== (feeAmount === 0n))
|
|
673
|
+
throw new Error("invalid fee context");
|
|
674
|
+
return { feeRecipient, feeAmount };
|
|
675
|
+
}
|
|
676
|
+
|
|
672
677
|
// src/credit-create.ts
|
|
678
|
+
import {
|
|
679
|
+
AbiCoder as AbiCoder2,
|
|
680
|
+
dataLength as dataLength2,
|
|
681
|
+
getAddress as getAddress5,
|
|
682
|
+
Interface as Interface3,
|
|
683
|
+
isHexString as isHexString3,
|
|
684
|
+
keccak256 as keccak2563,
|
|
685
|
+
ParamType as ParamType2
|
|
686
|
+
} from "ethers";
|
|
687
|
+
import { computeWalletAuthorizationDigest, walletAuthorizationTypedData } from "@invisi-labs/core";
|
|
673
688
|
var creationTuple = [
|
|
674
|
-
"(address token,(uint256 treeId,bytes32 merkleRoot)[] sources,bytes32[] nullifiers,bytes32 creditCommitment,bytes32 changeCommitment,address owner,uint256 expiry,uint256 deadline)"
|
|
689
|
+
"(address token,(uint256 treeId,bytes32 merkleRoot)[] sources,bytes32[] nullifiers,bytes32 creditCommitment,bytes32 changeCommitment,address owner,uint256 expiry,uint256 deadline,address feeRecipient,uint256 feeAmount)"
|
|
675
690
|
][0];
|
|
676
691
|
var CREATE_CREDIT_FIELDS = [
|
|
677
692
|
"token",
|
|
@@ -681,25 +696,31 @@ var CREATE_CREDIT_FIELDS = [
|
|
|
681
696
|
"changeCommitment",
|
|
682
697
|
"owner",
|
|
683
698
|
"expiry",
|
|
684
|
-
"deadline"
|
|
699
|
+
"deadline",
|
|
700
|
+
"feeRecipient",
|
|
701
|
+
"feeAmount"
|
|
685
702
|
];
|
|
686
703
|
function validateCreateCreditRequest(c, p, cs, funding = {}) {
|
|
687
704
|
known(p, CREATE_CREDIT_FIELDS);
|
|
688
|
-
if (
|
|
705
|
+
if (getAddress5(p.token) !== getAddress5(c.tokenAddress))
|
|
689
706
|
throw new Error("request token mismatch");
|
|
690
|
-
const ctx = normalizeContext(c), ns = notes(p.nullifiers, "nullifiers"), sources = normalizeSources(p.sources, ns.length, 10), creditCommitment = word(field(p.creditCommitment)), changeCommitment = word(field(p.changeCommitment)), owner =
|
|
707
|
+
const ctx = normalizeContext(c), ns = notes(p.nullifiers, "nullifiers"), sources = normalizeSources(p.sources, ns.length, 10), creditCommitment = word(field(p.creditCommitment)), changeCommitment = word(field(p.changeCommitment)), owner = getAddress5(p.owner), expiry = uint(p.expiry, 64, "expiry"), deadline = checkDeadline(c, p.deadline), f = normalizeFunding(funding);
|
|
691
708
|
if (BigInt(creditCommitment) === 0n || creditCommitment === changeCommitment)
|
|
692
709
|
throw new Error("zero or duplicate commitment");
|
|
693
710
|
if (BigInt(owner) === 0n || expiry === 0n || c.now !== void 0 && expiry <= c.now)
|
|
694
711
|
throw new Error("owner must be nonzero and expiry future");
|
|
695
712
|
if (dense(cs, "deliveries").length !== 3) throw new Error("deliveries count mismatch");
|
|
696
713
|
const deliveries = cs.map(
|
|
697
|
-
(v, i) => normalizeOpaqueDelivery(v, {
|
|
714
|
+
(v, i) => normalizeOpaqueDelivery(v, {
|
|
715
|
+
empty: i === 2 && BigInt(changeCommitment) === 0n,
|
|
716
|
+
allowEmpty: i === 2
|
|
717
|
+
})
|
|
698
718
|
);
|
|
699
719
|
if (ns.length === 0 && f.amount === 0n)
|
|
700
720
|
throw new Error("empty inputs require positive funding");
|
|
701
721
|
return {
|
|
702
722
|
...ctx,
|
|
723
|
+
...normalizeFee(p),
|
|
703
724
|
sources,
|
|
704
725
|
nullifiers: ns,
|
|
705
726
|
actualCount: ns.length,
|
|
@@ -738,7 +759,9 @@ function createCreditBaseInputs(c, p, cs, f = {}) {
|
|
|
738
759
|
r.expiry,
|
|
739
760
|
r.deadline,
|
|
740
761
|
r.funding.amount,
|
|
741
|
-
BigInt(r.funding.payer)
|
|
762
|
+
BigInt(r.funding.payer),
|
|
763
|
+
BigInt(r.feeRecipient),
|
|
764
|
+
r.feeAmount
|
|
742
765
|
].map(word);
|
|
743
766
|
}
|
|
744
767
|
function createCreditPublicInputs(c, p, deliveries, funding = {}) {
|
|
@@ -771,7 +794,7 @@ function createCreditRequestHash(p, cs, f = {}) {
|
|
|
771
794
|
].map((parameter) => ParamType2.from(parameter)),
|
|
772
795
|
[
|
|
773
796
|
keccak2563(new TextEncoder().encode("InvisiCreateCredit")),
|
|
774
|
-
p,
|
|
797
|
+
{ ...p, ...normalizeFee(p) },
|
|
775
798
|
deliveriesHash(cs),
|
|
776
799
|
r.funding.payer,
|
|
777
800
|
r.funding.amount
|
|
@@ -809,7 +832,7 @@ function buildCreateCreditCalldata(p) {
|
|
|
809
832
|
return {
|
|
810
833
|
data: new Interface3(invisiProtocolAbi).encodeFunctionData("createCredit", [
|
|
811
834
|
encodeCreditProof(p.proof),
|
|
812
|
-
p.params,
|
|
835
|
+
{ ...p.params, ...normalizeFee(p.params) },
|
|
813
836
|
p.deliveries,
|
|
814
837
|
r.funding
|
|
815
838
|
]),
|
|
@@ -826,7 +849,7 @@ function encodeCreditProof(proof) {
|
|
|
826
849
|
}
|
|
827
850
|
|
|
828
851
|
// src/credit-lifecycle.ts
|
|
829
|
-
import { AbiCoder as AbiCoder3, getAddress as
|
|
852
|
+
import { AbiCoder as AbiCoder3, getAddress as getAddress6, Interface as Interface4, keccak256 as keccak2564, ParamType as ParamType3 } from "ethers";
|
|
830
853
|
import {
|
|
831
854
|
creditPeriods,
|
|
832
855
|
computeWalletAuthorizationDigest as computeWalletAuthorizationDigest2,
|
|
@@ -856,7 +879,7 @@ function validateCreditDrawRequest(c, p, cs) {
|
|
|
856
879
|
"totalAmount",
|
|
857
880
|
"deadline"
|
|
858
881
|
]);
|
|
859
|
-
if (
|
|
882
|
+
if (getAddress6(p.token) !== getAddress6(c.tokenAddress))
|
|
860
883
|
throw new Error("request token mismatch");
|
|
861
884
|
const ctx = normalizeContext(c), ns = notes(p.nullifiers, "nullifiers"), profile = selectCreditDrawCircuit(ns.length), sources = normalizeSources(p.sources, ns.length, profile.maxSize);
|
|
862
885
|
for (const [key, v] of Object.entries({
|
|
@@ -874,7 +897,7 @@ function validateCreditDrawRequest(c, p, cs) {
|
|
|
874
897
|
if (BigInt(remainderCommitments[i]) === 0n && BigInt(recoveryAmounts[i]) !== 0n)
|
|
875
898
|
throw new Error("full draw requires zero recovery amount");
|
|
876
899
|
}
|
|
877
|
-
const spender =
|
|
900
|
+
const spender = getAddress6(p.spender), totalAmount = uint(p.totalAmount, profile.totalBits, "totalAmount");
|
|
878
901
|
if (BigInt(spender) === 0n || totalAmount === 0n)
|
|
879
902
|
throw new Error("spender and total amount must be positive");
|
|
880
903
|
if (dense(cs, "deliveries").length !== 2 * ns.length)
|
|
@@ -927,13 +950,25 @@ function creditDrawBaseInputs(c, p, cs) {
|
|
|
927
950
|
].map(word);
|
|
928
951
|
}
|
|
929
952
|
function validateCancelCreditRequest(c, p) {
|
|
930
|
-
known(p, [
|
|
931
|
-
|
|
953
|
+
known(p, [
|
|
954
|
+
"token",
|
|
955
|
+
"source",
|
|
956
|
+
"nullifier",
|
|
957
|
+
"owner",
|
|
958
|
+
"amount",
|
|
959
|
+
"deadline",
|
|
960
|
+
"feeRecipient",
|
|
961
|
+
"feeAmount"
|
|
962
|
+
]);
|
|
963
|
+
if (getAddress6(p.token) !== getAddress6(c.tokenAddress))
|
|
932
964
|
throw new Error("request token mismatch");
|
|
933
|
-
const ctx = normalizeContext(c), source = normalizeSources([p.source], 1, 1)[0], nullifier = notes([p.nullifier], "nullifier")[0], owner =
|
|
965
|
+
const ctx = normalizeContext(c), source = normalizeSources([p.source], 1, 1)[0], nullifier = notes([p.nullifier], "nullifier")[0], owner = getAddress6(p.owner), amount = uint(p.amount, 126, "amount");
|
|
934
966
|
if (BigInt(owner) === 0n || amount === 0n) throw new Error("owner and amount must be positive");
|
|
967
|
+
const fee = normalizeFee(p);
|
|
968
|
+
if (fee.feeAmount >= amount) throw new Error("fee must leave a positive owner refund");
|
|
935
969
|
return {
|
|
936
970
|
...ctx,
|
|
971
|
+
...fee,
|
|
937
972
|
source,
|
|
938
973
|
nullifier,
|
|
939
974
|
owner,
|
|
@@ -952,7 +987,9 @@ function cancelCreditBaseInputs(c, p) {
|
|
|
952
987
|
BigInt(r.source.merkleRoot),
|
|
953
988
|
BigInt(r.nullifier),
|
|
954
989
|
r.amount,
|
|
955
|
-
r.deadline
|
|
990
|
+
r.deadline,
|
|
991
|
+
BigInt(r.feeRecipient),
|
|
992
|
+
r.feeAmount
|
|
956
993
|
].map(word);
|
|
957
994
|
}
|
|
958
995
|
function validateTopUpCreditRequest(c, p, cs, funding = {}) {
|
|
@@ -976,10 +1013,10 @@ function topUpCreditBaseInputs(c, p, cs, f = {}) {
|
|
|
976
1013
|
];
|
|
977
1014
|
}
|
|
978
1015
|
var cancelTuple = [
|
|
979
|
-
"(address token,(uint256 treeId,bytes32 merkleRoot) source,bytes32 nullifier,address owner,uint256 amount,uint256 deadline)"
|
|
1016
|
+
"(address token,(uint256 treeId,bytes32 merkleRoot) source,bytes32 nullifier,address owner,uint256 amount,uint256 deadline,address feeRecipient,uint256 feeAmount)"
|
|
980
1017
|
][0];
|
|
981
1018
|
var topTuple = [
|
|
982
|
-
"((address token,(uint256 treeId,bytes32 merkleRoot)[] sources,bytes32[] nullifiers,bytes32 creditCommitment,bytes32 changeCommitment,address owner,uint256 expiry,uint256 deadline) creation,(uint256 treeId,bytes32 merkleRoot) creditSource,bytes32 creditNullifier,uint256 previousExpiry)"
|
|
1019
|
+
"((address token,(uint256 treeId,bytes32 merkleRoot)[] sources,bytes32[] nullifiers,bytes32 creditCommitment,bytes32 changeCommitment,address owner,uint256 expiry,uint256 deadline,address feeRecipient,uint256 feeAmount) creation,(uint256 treeId,bytes32 merkleRoot) creditSource,bytes32 creditNullifier,uint256 previousExpiry)"
|
|
983
1020
|
][0];
|
|
984
1021
|
var hashContext2 = {
|
|
985
1022
|
chainId: 0n,
|
|
@@ -991,7 +1028,10 @@ function cancelCreditRequestHash(p) {
|
|
|
991
1028
|
return keccak2564(
|
|
992
1029
|
AbiCoder3.defaultAbiCoder().encode(
|
|
993
1030
|
[{ type: "bytes32" }, cancelTuple].map((parameter) => ParamType3.from(parameter)),
|
|
994
|
-
[
|
|
1031
|
+
[
|
|
1032
|
+
keccak2564(new TextEncoder().encode("InvisiCancelCredit")),
|
|
1033
|
+
{ ...p, ...normalizeFee(p) }
|
|
1034
|
+
]
|
|
995
1035
|
)
|
|
996
1036
|
);
|
|
997
1037
|
}
|
|
@@ -1013,7 +1053,7 @@ function topUpCreditRequestHash(p, cs, f = {}) {
|
|
|
1013
1053
|
].map((parameter) => ParamType3.from(parameter)),
|
|
1014
1054
|
[
|
|
1015
1055
|
keccak2564(new TextEncoder().encode("InvisiTopUpCredit")),
|
|
1016
|
-
p,
|
|
1056
|
+
{ ...p, creation: { ...p.creation, ...normalizeFee(p.creation) } },
|
|
1017
1057
|
deliveriesHash(cs),
|
|
1018
1058
|
r.creation.funding.payer,
|
|
1019
1059
|
r.creation.funding.amount
|
|
@@ -1101,7 +1141,7 @@ function buildCancelCreditCalldata(p) {
|
|
|
1101
1141
|
return {
|
|
1102
1142
|
data: new Interface4(invisiProtocolAbi).encodeFunctionData("cancelCredit", [
|
|
1103
1143
|
encodeCreditProof(p.proof),
|
|
1104
|
-
p.params
|
|
1144
|
+
{ ...p.params, ...normalizeFee(p.params) }
|
|
1105
1145
|
])
|
|
1106
1146
|
};
|
|
1107
1147
|
}
|
|
@@ -1111,7 +1151,7 @@ function buildTopUpCreditCalldata(p) {
|
|
|
1111
1151
|
return {
|
|
1112
1152
|
data: new Interface4(invisiProtocolAbi).encodeFunctionData("topUpCredit", [
|
|
1113
1153
|
encodeCreditProof(p.proof),
|
|
1114
|
-
p.params,
|
|
1154
|
+
{ ...p.params, creation: { ...p.params.creation, ...normalizeFee(p.params.creation) } },
|
|
1115
1155
|
p.deliveries,
|
|
1116
1156
|
r.creation.funding
|
|
1117
1157
|
]),
|
|
@@ -1120,7 +1160,7 @@ function buildTopUpCreditCalldata(p) {
|
|
|
1120
1160
|
}
|
|
1121
1161
|
|
|
1122
1162
|
// src/funds.ts
|
|
1123
|
-
import { AbiCoder as AbiCoder4, getAddress as
|
|
1163
|
+
import { AbiCoder as AbiCoder4, getAddress as getAddress7, Interface as Interface5, keccak256 as keccak2565, ParamType as ParamType4, TypedDataEncoder as TypedDataEncoder2 } from "ethers";
|
|
1124
1164
|
import { computeNoteCommitment, walletAuthorizationTypedData as walletAuthorizationTypedData3 } from "@invisi-labs/core";
|
|
1125
1165
|
var TRANSACT_CAPACITIES = [14, 56, 112, 168];
|
|
1126
1166
|
function selectTransactCapacity(inputs, outputs) {
|
|
@@ -1130,7 +1170,7 @@ function selectTransactCapacity(inputs, outputs) {
|
|
|
1130
1170
|
}
|
|
1131
1171
|
function normalizeTransactRequest(c, p, cs, funding = {}) {
|
|
1132
1172
|
const ctx = normalizeContext(c);
|
|
1133
|
-
if (
|
|
1173
|
+
if (getAddress7(p.token) !== ctx.tokenAddress)
|
|
1134
1174
|
throw new Error("request token mismatch");
|
|
1135
1175
|
known(p, [
|
|
1136
1176
|
"token",
|
|
@@ -1139,12 +1179,21 @@ function normalizeTransactRequest(c, p, cs, funding = {}) {
|
|
|
1139
1179
|
"outputCommitments",
|
|
1140
1180
|
"withdrawalAddress",
|
|
1141
1181
|
"withdrawalAmount",
|
|
1142
|
-
"deadline"
|
|
1182
|
+
"deadline",
|
|
1183
|
+
"feeRecipient",
|
|
1184
|
+
"feeAmount"
|
|
1143
1185
|
]);
|
|
1144
1186
|
const ns = notes(p.nullifiers, "nullifiers"), os = notes(p.outputCommitments, "outputCommitments"), capacity = selectTransactCapacity(ns.length, os.length);
|
|
1145
|
-
const sources = normalizeSources(p.sources, ns.length, capacity), deliveries = dense(cs, "deliveries").map(
|
|
1187
|
+
const sources = normalizeSources(p.sources, ns.length, capacity), deliveries = dense(cs, "deliveries").map(
|
|
1188
|
+
(v) => normalizeOpaqueDelivery(v, { allowEmpty: true })
|
|
1189
|
+
);
|
|
1146
1190
|
if (deliveries.length !== os.length) throw new Error("deliveries count mismatch");
|
|
1147
|
-
const withdrawalAmount = uint(p.withdrawalAmount, 128, "withdrawalAmount"), withdrawalAddress =
|
|
1191
|
+
const withdrawalAmount = uint(p.withdrawalAmount, 128, "withdrawalAmount"), withdrawalAddress = getAddress7(p.withdrawalAddress), f = normalizeFunding(funding);
|
|
1192
|
+
const feeAmount = uint(p.feeAmount ?? 0n, 128, "feeAmount");
|
|
1193
|
+
const feeRecipient = getAddress7(
|
|
1194
|
+
p.feeRecipient ?? "0x0000000000000000000000000000000000000000"
|
|
1195
|
+
);
|
|
1196
|
+
if (feeAmount === 0n !== (BigInt(feeRecipient) === 0n)) throw new Error("invalid fee");
|
|
1148
1197
|
if (withdrawalAmount === 0n !== (BigInt(withdrawalAddress) === 0n) || os.length === 0 && withdrawalAmount === 0n)
|
|
1149
1198
|
throw new Error("invalid withdrawal");
|
|
1150
1199
|
if (ns.length === 0 && (f.amount === 0n || withdrawalAmount !== 0n))
|
|
@@ -1171,6 +1220,8 @@ function normalizeTransactRequest(c, p, cs, funding = {}) {
|
|
|
1171
1220
|
deliveriesHash: deliveriesHash(deliveries),
|
|
1172
1221
|
withdrawalAddress,
|
|
1173
1222
|
withdrawalAmount,
|
|
1223
|
+
feeRecipient,
|
|
1224
|
+
feeAmount,
|
|
1174
1225
|
deadline: checkDeadline(c, p.deadline),
|
|
1175
1226
|
depositAmount: f.amount,
|
|
1176
1227
|
depositPayer: f.payer,
|
|
@@ -1195,7 +1246,9 @@ function transactPublicInputs(c, p, cs, f = {}) {
|
|
|
1195
1246
|
r.withdrawalAmount,
|
|
1196
1247
|
r.deadline,
|
|
1197
1248
|
r.depositAmount,
|
|
1198
|
-
BigInt(r.depositPayer)
|
|
1249
|
+
BigInt(r.depositPayer),
|
|
1250
|
+
BigInt(r.feeRecipient),
|
|
1251
|
+
r.feeAmount
|
|
1199
1252
|
].map(word);
|
|
1200
1253
|
}
|
|
1201
1254
|
function encodeTransactTypedData(c, p, deliveries, f = {}) {
|
|
@@ -1208,10 +1261,10 @@ function encodeTransactTypedData(c, p, deliveries, f = {}) {
|
|
|
1208
1261
|
});
|
|
1209
1262
|
}
|
|
1210
1263
|
var singleTuple = [
|
|
1211
|
-
"(address token,bytes32 merkleRoot,bytes32[] nullifiers,bytes32[] outputCommitments,uint256 inputTreeId,address withdrawalAddress,uint256 withdrawalAmount,uint256 deadline)"
|
|
1264
|
+
"(address token,bytes32 merkleRoot,bytes32[] nullifiers,bytes32[] outputCommitments,uint256 inputTreeId,address withdrawalAddress,uint256 withdrawalAmount,uint256 deadline,address feeRecipient,uint256 feeAmount)"
|
|
1212
1265
|
][0];
|
|
1213
1266
|
var crossTuple = [
|
|
1214
|
-
"(address token,(uint256 treeId,bytes32 merkleRoot)[] sources,bytes32[] nullifiers,bytes32[] outputCommitments,address withdrawalAddress,uint256 withdrawalAmount,uint256 deadline)"
|
|
1267
|
+
"(address token,(uint256 treeId,bytes32 merkleRoot)[] sources,bytes32[] nullifiers,bytes32[] outputCommitments,address withdrawalAddress,uint256 withdrawalAmount,uint256 deadline,address feeRecipient,uint256 feeAmount)"
|
|
1215
1268
|
][0];
|
|
1216
1269
|
function transactFundingRequestHash(proof, p, cs) {
|
|
1217
1270
|
const single = {
|
|
@@ -1222,7 +1275,9 @@ function transactFundingRequestHash(proof, p, cs) {
|
|
|
1222
1275
|
inputTreeId: p.sources[0]?.treeId ?? 0n,
|
|
1223
1276
|
withdrawalAddress: p.withdrawalAddress,
|
|
1224
1277
|
withdrawalAmount: p.withdrawalAmount,
|
|
1225
|
-
deadline: p.deadline
|
|
1278
|
+
deadline: p.deadline,
|
|
1279
|
+
feeRecipient: p.feeRecipient ?? "0x0000000000000000000000000000000000000000",
|
|
1280
|
+
feeAmount: p.feeAmount ?? 0n
|
|
1226
1281
|
};
|
|
1227
1282
|
return p.sources.length > 1 ? keccak2565(
|
|
1228
1283
|
AbiCoder4.defaultAbiCoder().encode(
|
|
@@ -1232,7 +1287,7 @@ function transactFundingRequestHash(proof, p, cs) {
|
|
|
1232
1287
|
[
|
|
1233
1288
|
keccak2565(new TextEncoder().encode("InvisiCrossTreeTransact")),
|
|
1234
1289
|
keccak2565(proof),
|
|
1235
|
-
p,
|
|
1290
|
+
{ ...p, feeRecipient: single.feeRecipient, feeAmount: single.feeAmount },
|
|
1236
1291
|
deliveriesHash(cs)
|
|
1237
1292
|
]
|
|
1238
1293
|
)
|
|
@@ -1273,7 +1328,9 @@ function buildTransactCalldata(p) {
|
|
|
1273
1328
|
outputCommitments: r.outputCommitments,
|
|
1274
1329
|
withdrawalAddress: r.withdrawalAddress,
|
|
1275
1330
|
withdrawalAmount: r.withdrawalAmount,
|
|
1276
|
-
deadline: r.deadline
|
|
1331
|
+
deadline: r.deadline,
|
|
1332
|
+
feeRecipient: r.feeRecipient,
|
|
1333
|
+
feeAmount: r.feeAmount
|
|
1277
1334
|
},
|
|
1278
1335
|
deliveries: p.deliveries,
|
|
1279
1336
|
funding: r.funding
|
|
@@ -1287,7 +1344,7 @@ function buildTransactCalldata(p) {
|
|
|
1287
1344
|
function buildTransactAggregateCalldata(p) {
|
|
1288
1345
|
if (![4, 8, 12].includes(dense(p.requests, "requests").length))
|
|
1289
1346
|
throw new Error("aggregate requires 4, 8 or 12 requests");
|
|
1290
|
-
|
|
1347
|
+
const requests = p.requests.map((request) => {
|
|
1291
1348
|
const r = normalizeTransactRequest(
|
|
1292
1349
|
{ ...p.context, tokenAddress: request.params.token },
|
|
1293
1350
|
request.params,
|
|
@@ -1296,21 +1353,25 @@ function buildTransactAggregateCalldata(p) {
|
|
|
1296
1353
|
);
|
|
1297
1354
|
if (r.capacity !== 14) throw new Error("aggregate supports only capacity 14");
|
|
1298
1355
|
validateFundingSubmission(r.funding, p.caller, p.context.now);
|
|
1299
|
-
|
|
1356
|
+
return {
|
|
1357
|
+
...request,
|
|
1358
|
+
params: { ...request.params, feeRecipient: r.feeRecipient, feeAmount: r.feeAmount }
|
|
1359
|
+
};
|
|
1360
|
+
});
|
|
1300
1361
|
return {
|
|
1301
1362
|
data: new Interface5(
|
|
1302
1363
|
invisiProtocolAbi.filter(
|
|
1303
1364
|
(item) => item.type === "function" && item.name === "transact" && item.inputs[1]?.type === "tuple[]"
|
|
1304
1365
|
)
|
|
1305
|
-
).encodeFunctionData("transact", [p.proof,
|
|
1366
|
+
).encodeFunctionData("transact", [p.proof, requests]),
|
|
1306
1367
|
capacity: 14
|
|
1307
1368
|
};
|
|
1308
1369
|
}
|
|
1309
1370
|
async function validateShieldRequest(p) {
|
|
1310
1371
|
normalizeContext(p.context);
|
|
1311
|
-
if (
|
|
1372
|
+
if (getAddress7(p.params.token) !== getAddress7(p.context.tokenAddress))
|
|
1312
1373
|
throw new Error("request token mismatch");
|
|
1313
|
-
known(p.params, ["token", "outputCommitments", "deadline"]);
|
|
1374
|
+
known(p.params, ["token", "outputCommitments", "deadline", "feeRecipient", "feeAmount"]);
|
|
1314
1375
|
checkDeadline(p.context, p.params.deadline);
|
|
1315
1376
|
const outputs = dense(p.outputs, "outputs"), commitments = notes(p.params.outputCommitments, "outputCommitments"), cs = dense(p.deliveries, "deliveries"), f = normalizeFunding(p.funding);
|
|
1316
1377
|
if (outputs.length < 1 || outputs.length > 10 || commitments.length !== outputs.length || cs.length !== outputs.length)
|
|
@@ -1321,7 +1382,7 @@ async function validateShieldRequest(p) {
|
|
|
1321
1382
|
uint(o.amount, 128, "amount");
|
|
1322
1383
|
if (o.amount === 0n) throw new Error("amount must be positive");
|
|
1323
1384
|
field(o.identity);
|
|
1324
|
-
normalizeOpaqueDelivery(cs[i]);
|
|
1385
|
+
normalizeOpaqueDelivery(cs[i], { allowEmpty: true });
|
|
1325
1386
|
if (await computeNoteCommitment(
|
|
1326
1387
|
p.context.chainId,
|
|
1327
1388
|
o.identity,
|
|
@@ -1331,7 +1392,8 @@ async function validateShieldRequest(p) {
|
|
|
1331
1392
|
throw new Error("output commitment mismatch");
|
|
1332
1393
|
total += o.amount;
|
|
1333
1394
|
}
|
|
1334
|
-
if (total !== f.amount)
|
|
1395
|
+
if (total + normalizeFee(p.params).feeAmount !== f.amount)
|
|
1396
|
+
throw new Error("funding must equal output total plus fee");
|
|
1335
1397
|
return f;
|
|
1336
1398
|
}
|
|
1337
1399
|
function shieldFundingRequestHash(params, outputs, cs) {
|
|
@@ -1345,13 +1407,13 @@ function shieldFundingRequestHash(params, outputs, cs) {
|
|
|
1345
1407
|
AbiCoder4.defaultAbiCoder().encode(
|
|
1346
1408
|
[
|
|
1347
1409
|
"bytes32",
|
|
1348
|
-
"(address token,bytes32[] outputCommitments,uint256 deadline)",
|
|
1410
|
+
"(address token,bytes32[] outputCommitments,uint256 deadline,address feeRecipient,uint256 feeAmount)",
|
|
1349
1411
|
"bytes32",
|
|
1350
1412
|
"bytes32"
|
|
1351
1413
|
].map((parameter) => ParamType4.from(parameter)),
|
|
1352
1414
|
[
|
|
1353
1415
|
keccak2565(new TextEncoder().encode("InvisiShield")),
|
|
1354
|
-
params,
|
|
1416
|
+
{ ...params, ...normalizeFee(params) },
|
|
1355
1417
|
outputHash,
|
|
1356
1418
|
deliveriesHash(cs)
|
|
1357
1419
|
]
|
|
@@ -1378,7 +1440,7 @@ async function buildShieldCalldata(p) {
|
|
|
1378
1440
|
validateFundingSubmission(f, p.caller, p.context.now);
|
|
1379
1441
|
return {
|
|
1380
1442
|
data: new Interface5(invisiProtocolAbi).encodeFunctionData("shield", [
|
|
1381
|
-
p.params,
|
|
1443
|
+
{ ...p.params, ...normalizeFee(p.params) },
|
|
1382
1444
|
p.outputs,
|
|
1383
1445
|
p.deliveries,
|
|
1384
1446
|
f
|
|
@@ -1445,7 +1507,7 @@ function encodeAggregateFundingTypedData(c, r) {
|
|
|
1445
1507
|
}
|
|
1446
1508
|
|
|
1447
1509
|
// src/Protocol.ts
|
|
1448
|
-
import { Contract as Contract2, getAddress as
|
|
1510
|
+
import { Contract as Contract2, getAddress as getAddress8, keccak256 as keccak2567 } from "ethers";
|
|
1449
1511
|
import {
|
|
1450
1512
|
defineDeployment
|
|
1451
1513
|
} from "@invisi-labs/rpc";
|
|
@@ -1566,7 +1628,7 @@ var Protocol = class _Protocol {
|
|
|
1566
1628
|
const reader = "getNetwork" in connection ? {
|
|
1567
1629
|
getChainId: async () => (await connection.getNetwork()).chainId,
|
|
1568
1630
|
getCode: async (address) => await connection.getCode(address),
|
|
1569
|
-
getProtocolAddressRegistry: async (address) =>
|
|
1631
|
+
getProtocolAddressRegistry: async (address) => getAddress8(
|
|
1570
1632
|
await new Contract2(
|
|
1571
1633
|
address,
|
|
1572
1634
|
["function addressRegistry() view returns (address)"],
|
|
@@ -1592,9 +1654,9 @@ var Protocol = class _Protocol {
|
|
|
1592
1654
|
if (registry) {
|
|
1593
1655
|
if (!reader.getProtocolAddressRegistry)
|
|
1594
1656
|
throw new Error("registry binding reader capability is missing");
|
|
1595
|
-
if (
|
|
1657
|
+
if (getAddress8(
|
|
1596
1658
|
await reader.getProtocolAddressRegistry(this.context.protocolAddress)
|
|
1597
|
-
) !==
|
|
1659
|
+
) !== getAddress8(registry.address))
|
|
1598
1660
|
throw new Error("protocol registry binding mismatch");
|
|
1599
1661
|
const registryCode = await reader.getCode(registry.address);
|
|
1600
1662
|
if (!/^0x(?:[0-9a-fA-F]{2})+$/.test(registryCode) || keccak2567(registryCode) !== registry.runtimeCodeHash)
|
|
@@ -1611,7 +1673,7 @@ var Protocol = class _Protocol {
|
|
|
1611
1673
|
/** Build an operation context for one asset within this same deployment. */
|
|
1612
1674
|
forToken(tokenAddress) {
|
|
1613
1675
|
return new TokenProtocol(
|
|
1614
|
-
{ ...this.context, tokenAddress:
|
|
1676
|
+
{ ...this.context, tokenAddress: getAddress8(tokenAddress) },
|
|
1615
1677
|
{ expectedRuntimeCodeHash: this.deployment.protocol.runtimeCodeHash }
|
|
1616
1678
|
);
|
|
1617
1679
|
}
|
|
@@ -1628,7 +1690,7 @@ import {
|
|
|
1628
1690
|
async function verifyNoteCommitment(params) {
|
|
1629
1691
|
const expected = await computeNoteCommitment2(
|
|
1630
1692
|
params.chainId,
|
|
1631
|
-
await computeNoteIdentity(BigInt(params.
|
|
1693
|
+
await computeNoteIdentity(BigInt(params.ownerAddress), BigInt(params.nonce)),
|
|
1632
1694
|
BigInt(params.tokenAddress),
|
|
1633
1695
|
params.amount
|
|
1634
1696
|
);
|
|
@@ -1675,12 +1737,12 @@ import {
|
|
|
1675
1737
|
// src/witness-layouts.json
|
|
1676
1738
|
var witness_layouts_default = {
|
|
1677
1739
|
transact_user_slots14: {
|
|
1678
|
-
artifactSha256: "
|
|
1740
|
+
artifactSha256: "df9458f0be9c8905241ee74e5f11c0e1c348ef749fe1a9d599034a983f08dbd5",
|
|
1679
1741
|
keys: {
|
|
1680
|
-
evm: "
|
|
1681
|
-
"noir-recursive": "
|
|
1742
|
+
evm: "a9db580b09d05f09d4ea58b8d9755855525b8cc20beee4b1fbfe4cad10251e4e",
|
|
1743
|
+
"noir-recursive": "912191fc9484b2c0ab869d44900054b1a7c25c3256177abfc102884f3fa7d7ed"
|
|
1682
1744
|
},
|
|
1683
|
-
publicInputCount:
|
|
1745
|
+
publicInputCount: 59,
|
|
1684
1746
|
public: [
|
|
1685
1747
|
{
|
|
1686
1748
|
name: "chain_id",
|
|
@@ -1762,6 +1824,16 @@ var witness_layouts_default = {
|
|
|
1762
1824
|
count: 1,
|
|
1763
1825
|
array: false
|
|
1764
1826
|
},
|
|
1827
|
+
{
|
|
1828
|
+
name: "fee_recipient",
|
|
1829
|
+
count: 1,
|
|
1830
|
+
array: false
|
|
1831
|
+
},
|
|
1832
|
+
{
|
|
1833
|
+
name: "fee_amount",
|
|
1834
|
+
count: 1,
|
|
1835
|
+
array: false
|
|
1836
|
+
},
|
|
1765
1837
|
{
|
|
1766
1838
|
name: "auth_digest_high",
|
|
1767
1839
|
count: 1,
|
|
@@ -1774,11 +1846,11 @@ var witness_layouts_default = {
|
|
|
1774
1846
|
}
|
|
1775
1847
|
],
|
|
1776
1848
|
private: [
|
|
1777
|
-
"
|
|
1849
|
+
"input_owner_address",
|
|
1778
1850
|
"public_key_x",
|
|
1779
1851
|
"public_key_y",
|
|
1780
1852
|
"signature",
|
|
1781
|
-
"
|
|
1853
|
+
"output_identities",
|
|
1782
1854
|
"amounts",
|
|
1783
1855
|
"nonces",
|
|
1784
1856
|
"leaf_indices",
|
|
@@ -1787,11 +1859,11 @@ var witness_layouts_default = {
|
|
|
1787
1859
|
]
|
|
1788
1860
|
},
|
|
1789
1861
|
transact_user_slots56: {
|
|
1790
|
-
artifactSha256: "
|
|
1862
|
+
artifactSha256: "370299e1ee32a57b6a81ccdbf5e95efef144bee17d38d402bbbfbaa392d355d8",
|
|
1791
1863
|
keys: {
|
|
1792
|
-
evm: "
|
|
1864
|
+
evm: "2bb2fdf9ef33200038aa6e0a9f35e2a7252bf3946f5b5d68dd0ae85172adeddf"
|
|
1793
1865
|
},
|
|
1794
|
-
publicInputCount:
|
|
1866
|
+
publicInputCount: 185,
|
|
1795
1867
|
public: [
|
|
1796
1868
|
{
|
|
1797
1869
|
name: "chain_id",
|
|
@@ -1873,6 +1945,16 @@ var witness_layouts_default = {
|
|
|
1873
1945
|
count: 1,
|
|
1874
1946
|
array: false
|
|
1875
1947
|
},
|
|
1948
|
+
{
|
|
1949
|
+
name: "fee_recipient",
|
|
1950
|
+
count: 1,
|
|
1951
|
+
array: false
|
|
1952
|
+
},
|
|
1953
|
+
{
|
|
1954
|
+
name: "fee_amount",
|
|
1955
|
+
count: 1,
|
|
1956
|
+
array: false
|
|
1957
|
+
},
|
|
1876
1958
|
{
|
|
1877
1959
|
name: "auth_digest_high",
|
|
1878
1960
|
count: 1,
|
|
@@ -1885,11 +1967,11 @@ var witness_layouts_default = {
|
|
|
1885
1967
|
}
|
|
1886
1968
|
],
|
|
1887
1969
|
private: [
|
|
1888
|
-
"
|
|
1970
|
+
"input_owner_address",
|
|
1889
1971
|
"public_key_x",
|
|
1890
1972
|
"public_key_y",
|
|
1891
1973
|
"signature",
|
|
1892
|
-
"
|
|
1974
|
+
"output_identities",
|
|
1893
1975
|
"amounts",
|
|
1894
1976
|
"nonces",
|
|
1895
1977
|
"leaf_indices",
|
|
@@ -1898,11 +1980,11 @@ var witness_layouts_default = {
|
|
|
1898
1980
|
]
|
|
1899
1981
|
},
|
|
1900
1982
|
transact_user_slots112: {
|
|
1901
|
-
artifactSha256: "
|
|
1983
|
+
artifactSha256: "259417390705f5ced1cbd671582a2fe40dbf7a259d8717f4e90989dc4368ad91",
|
|
1902
1984
|
keys: {
|
|
1903
|
-
evm: "
|
|
1985
|
+
evm: "523652b9391818c0af0af8668ba2cd786be25ef00e6bcafa662ed829a32746a7"
|
|
1904
1986
|
},
|
|
1905
|
-
publicInputCount:
|
|
1987
|
+
publicInputCount: 353,
|
|
1906
1988
|
public: [
|
|
1907
1989
|
{
|
|
1908
1990
|
name: "chain_id",
|
|
@@ -1984,6 +2066,16 @@ var witness_layouts_default = {
|
|
|
1984
2066
|
count: 1,
|
|
1985
2067
|
array: false
|
|
1986
2068
|
},
|
|
2069
|
+
{
|
|
2070
|
+
name: "fee_recipient",
|
|
2071
|
+
count: 1,
|
|
2072
|
+
array: false
|
|
2073
|
+
},
|
|
2074
|
+
{
|
|
2075
|
+
name: "fee_amount",
|
|
2076
|
+
count: 1,
|
|
2077
|
+
array: false
|
|
2078
|
+
},
|
|
1987
2079
|
{
|
|
1988
2080
|
name: "auth_digest_high",
|
|
1989
2081
|
count: 1,
|
|
@@ -1996,11 +2088,11 @@ var witness_layouts_default = {
|
|
|
1996
2088
|
}
|
|
1997
2089
|
],
|
|
1998
2090
|
private: [
|
|
1999
|
-
"
|
|
2091
|
+
"input_owner_address",
|
|
2000
2092
|
"public_key_x",
|
|
2001
2093
|
"public_key_y",
|
|
2002
2094
|
"signature",
|
|
2003
|
-
"
|
|
2095
|
+
"output_identities",
|
|
2004
2096
|
"amounts",
|
|
2005
2097
|
"nonces",
|
|
2006
2098
|
"leaf_indices",
|
|
@@ -2009,11 +2101,11 @@ var witness_layouts_default = {
|
|
|
2009
2101
|
]
|
|
2010
2102
|
},
|
|
2011
2103
|
transact_user_slots168: {
|
|
2012
|
-
artifactSha256: "
|
|
2104
|
+
artifactSha256: "2a86703ca068c50f305d3b4b856ab3b2145d066da0bab894eac8e7c174c20292",
|
|
2013
2105
|
keys: {
|
|
2014
|
-
evm: "
|
|
2106
|
+
evm: "c9d821fdd5b8cfcdc7fe93e673a8c99487879a4680c8f1b86c0b5c05a3cad515"
|
|
2015
2107
|
},
|
|
2016
|
-
publicInputCount:
|
|
2108
|
+
publicInputCount: 521,
|
|
2017
2109
|
public: [
|
|
2018
2110
|
{
|
|
2019
2111
|
name: "chain_id",
|
|
@@ -2095,6 +2187,16 @@ var witness_layouts_default = {
|
|
|
2095
2187
|
count: 1,
|
|
2096
2188
|
array: false
|
|
2097
2189
|
},
|
|
2190
|
+
{
|
|
2191
|
+
name: "fee_recipient",
|
|
2192
|
+
count: 1,
|
|
2193
|
+
array: false
|
|
2194
|
+
},
|
|
2195
|
+
{
|
|
2196
|
+
name: "fee_amount",
|
|
2197
|
+
count: 1,
|
|
2198
|
+
array: false
|
|
2199
|
+
},
|
|
2098
2200
|
{
|
|
2099
2201
|
name: "auth_digest_high",
|
|
2100
2202
|
count: 1,
|
|
@@ -2107,11 +2209,11 @@ var witness_layouts_default = {
|
|
|
2107
2209
|
}
|
|
2108
2210
|
],
|
|
2109
2211
|
private: [
|
|
2110
|
-
"
|
|
2212
|
+
"input_owner_address",
|
|
2111
2213
|
"public_key_x",
|
|
2112
2214
|
"public_key_y",
|
|
2113
2215
|
"signature",
|
|
2114
|
-
"
|
|
2216
|
+
"output_identities",
|
|
2115
2217
|
"amounts",
|
|
2116
2218
|
"nonces",
|
|
2117
2219
|
"leaf_indices",
|
|
@@ -2120,11 +2222,11 @@ var witness_layouts_default = {
|
|
|
2120
2222
|
]
|
|
2121
2223
|
},
|
|
2122
2224
|
transact_aggregate_14_4: {
|
|
2123
|
-
artifactSha256: "
|
|
2225
|
+
artifactSha256: "4cd3f3d0dbcac9a48fec728450fd73a247321f655da02bd08db789e07b47527b",
|
|
2124
2226
|
keys: {
|
|
2125
|
-
evm: "
|
|
2227
|
+
evm: "6654b125cb96d5f4dd263c82cb34b0862bf63ff761fe5feab834f10283a0265d"
|
|
2126
2228
|
},
|
|
2127
|
-
publicInputCount:
|
|
2229
|
+
publicInputCount: 237,
|
|
2128
2230
|
public: [
|
|
2129
2231
|
{
|
|
2130
2232
|
name: "statements",
|
|
@@ -2144,11 +2246,11 @@ var witness_layouts_default = {
|
|
|
2144
2246
|
]
|
|
2145
2247
|
},
|
|
2146
2248
|
transact_aggregate_14_8: {
|
|
2147
|
-
artifactSha256: "
|
|
2249
|
+
artifactSha256: "b36ff5370043782364d41dbe00443970292b0240429f241c974ae6c9b10debfe",
|
|
2148
2250
|
keys: {
|
|
2149
|
-
evm: "
|
|
2251
|
+
evm: "2ad5b8b24109edf24197e97fbad35519d7d18558df19183ca3f91c4089ce4421"
|
|
2150
2252
|
},
|
|
2151
|
-
publicInputCount:
|
|
2253
|
+
publicInputCount: 473,
|
|
2152
2254
|
public: [
|
|
2153
2255
|
{
|
|
2154
2256
|
name: "statements",
|
|
@@ -2168,11 +2270,11 @@ var witness_layouts_default = {
|
|
|
2168
2270
|
]
|
|
2169
2271
|
},
|
|
2170
2272
|
transact_aggregate_14_12: {
|
|
2171
|
-
artifactSha256: "
|
|
2273
|
+
artifactSha256: "1191a92a333d826d4c4bd6a2e701a7751beb609904f8b928e3816f276d6fda67",
|
|
2172
2274
|
keys: {
|
|
2173
|
-
evm: "
|
|
2275
|
+
evm: "a8b06d969e97f53624fae05d08aa548182ad09db24fe60159fae61d243c0cb9d"
|
|
2174
2276
|
},
|
|
2175
|
-
publicInputCount:
|
|
2277
|
+
publicInputCount: 709,
|
|
2176
2278
|
public: [
|
|
2177
2279
|
{
|
|
2178
2280
|
name: "statements",
|
|
@@ -2192,11 +2294,11 @@ var witness_layouts_default = {
|
|
|
2192
2294
|
]
|
|
2193
2295
|
},
|
|
2194
2296
|
create_credit: {
|
|
2195
|
-
artifactSha256: "
|
|
2297
|
+
artifactSha256: "16a41fd585d5f925e4e93fd6a308e1ca8c90ea287778871cb0d214f0d0e223ce",
|
|
2196
2298
|
keys: {
|
|
2197
|
-
evm: "
|
|
2299
|
+
evm: "e8d3dc1f6922dbe1a0aa6016e65664be28d7005180ee943a4b237ac5518971bb"
|
|
2198
2300
|
},
|
|
2199
|
-
publicInputCount:
|
|
2301
|
+
publicInputCount: 48,
|
|
2200
2302
|
public: [
|
|
2201
2303
|
{
|
|
2202
2304
|
name: "chain_id",
|
|
@@ -2283,6 +2385,16 @@ var witness_layouts_default = {
|
|
|
2283
2385
|
count: 1,
|
|
2284
2386
|
array: false
|
|
2285
2387
|
},
|
|
2388
|
+
{
|
|
2389
|
+
name: "fee_recipient",
|
|
2390
|
+
count: 1,
|
|
2391
|
+
array: false
|
|
2392
|
+
},
|
|
2393
|
+
{
|
|
2394
|
+
name: "fee_amount",
|
|
2395
|
+
count: 1,
|
|
2396
|
+
array: false
|
|
2397
|
+
},
|
|
2286
2398
|
{
|
|
2287
2399
|
name: "auth_digest_high",
|
|
2288
2400
|
count: 1,
|
|
@@ -2841,11 +2953,11 @@ var witness_layouts_default = {
|
|
|
2841
2953
|
]
|
|
2842
2954
|
},
|
|
2843
2955
|
credit_cancel: {
|
|
2844
|
-
artifactSha256: "
|
|
2956
|
+
artifactSha256: "6485609280fe5a3d44ca9f1865b29b44253b3d2cd49770d000e7bb7a3db8e65d",
|
|
2845
2957
|
keys: {
|
|
2846
|
-
evm: "
|
|
2958
|
+
evm: "d74cf842d204cdf271c06a69482ddff11568e89630346b634d486205bec4bd9e"
|
|
2847
2959
|
},
|
|
2848
|
-
publicInputCount:
|
|
2960
|
+
publicInputCount: 13,
|
|
2849
2961
|
public: [
|
|
2850
2962
|
{
|
|
2851
2963
|
name: "chain_id",
|
|
@@ -2892,6 +3004,16 @@ var witness_layouts_default = {
|
|
|
2892
3004
|
count: 1,
|
|
2893
3005
|
array: false
|
|
2894
3006
|
},
|
|
3007
|
+
{
|
|
3008
|
+
name: "fee_recipient",
|
|
3009
|
+
count: 1,
|
|
3010
|
+
array: false
|
|
3011
|
+
},
|
|
3012
|
+
{
|
|
3013
|
+
name: "fee_amount",
|
|
3014
|
+
count: 1,
|
|
3015
|
+
array: false
|
|
3016
|
+
},
|
|
2895
3017
|
{
|
|
2896
3018
|
name: "auth_digest_high",
|
|
2897
3019
|
count: 1,
|
|
@@ -2925,11 +3047,11 @@ var witness_layouts_default = {
|
|
|
2925
3047
|
]
|
|
2926
3048
|
},
|
|
2927
3049
|
credit_top_up: {
|
|
2928
|
-
artifactSha256: "
|
|
3050
|
+
artifactSha256: "3004eea1c26ec8e33f8fc9ee171a3b6af250682efb607f7003ae58f8327998ab",
|
|
2929
3051
|
keys: {
|
|
2930
|
-
evm: "
|
|
3052
|
+
evm: "b7f378a871a27649c3f7fd1af554c8f87d99bcf0780b21972e910212ed4e5a0d"
|
|
2931
3053
|
},
|
|
2932
|
-
publicInputCount:
|
|
3054
|
+
publicInputCount: 52,
|
|
2933
3055
|
public: [
|
|
2934
3056
|
{
|
|
2935
3057
|
name: "chain_id",
|
|
@@ -3016,6 +3138,16 @@ var witness_layouts_default = {
|
|
|
3016
3138
|
count: 1,
|
|
3017
3139
|
array: false
|
|
3018
3140
|
},
|
|
3141
|
+
{
|
|
3142
|
+
name: "fee_recipient",
|
|
3143
|
+
count: 1,
|
|
3144
|
+
array: false
|
|
3145
|
+
},
|
|
3146
|
+
{
|
|
3147
|
+
name: "fee_amount",
|
|
3148
|
+
count: 1,
|
|
3149
|
+
array: false
|
|
3150
|
+
},
|
|
3019
3151
|
{
|
|
3020
3152
|
name: "credit_tree_id",
|
|
3021
3153
|
count: 1,
|
|
@@ -3177,7 +3309,7 @@ var WitnessBuilder = class {
|
|
|
3177
3309
|
words: words.slice(0, -2).map(BigInt)
|
|
3178
3310
|
};
|
|
3179
3311
|
check2(
|
|
3180
|
-
signed.
|
|
3312
|
+
signed.ownerAddress === identity && signed.digest === computeWalletAuthorizationDigest3(request),
|
|
3181
3313
|
"authorization statement mismatch"
|
|
3182
3314
|
);
|
|
3183
3315
|
const witness = signed.withWitness((value) => value);
|
|
@@ -3212,7 +3344,7 @@ var WitnessBuilder = class {
|
|
|
3212
3344
|
this.context(note);
|
|
3213
3345
|
return computeNoteCommitment3(
|
|
3214
3346
|
note.chainId,
|
|
3215
|
-
await computeNoteIdentity2(BigInt(note.
|
|
3347
|
+
await computeNoteIdentity2(BigInt(note.ownerAddress), note.nonce),
|
|
3216
3348
|
note.tokenAddress,
|
|
3217
3349
|
note.amount
|
|
3218
3350
|
);
|
|
@@ -3237,7 +3369,7 @@ var WitnessBuilder = class {
|
|
|
3237
3369
|
check2(inputs.length === nullifiers.length, "input count mismatch");
|
|
3238
3370
|
return Promise.all(
|
|
3239
3371
|
inputs.map(async (input, i) => {
|
|
3240
|
-
check2(input.note.
|
|
3372
|
+
check2(input.note.ownerAddress === identity, "input wallet mismatch");
|
|
3241
3373
|
const leaf = await this.noteLeaf(input.note);
|
|
3242
3374
|
check2(
|
|
3243
3375
|
await computeNoteNullifier(input.note.chainId, input.note.nonce, leaf) === nullifiers[i],
|
|
@@ -3253,8 +3385,8 @@ var WitnessBuilder = class {
|
|
|
3253
3385
|
p.inputs.length === n.inputCount && p.outputs.length === n.outputCount,
|
|
3254
3386
|
"note count mismatch"
|
|
3255
3387
|
);
|
|
3256
|
-
const identity = p.inputs[0]?.note.
|
|
3257
|
-
const unsignedSweep = !!identity && !p.authorization && n.outputCount === 0 && n.depositAmount === 0n && BigInt(p.params.withdrawalAddress) === BigInt(identity);
|
|
3388
|
+
const identity = p.inputs[0]?.note.ownerAddress;
|
|
3389
|
+
const unsignedSweep = !!identity && !p.authorization && n.outputCount === 0 && n.depositAmount === 0n && n.feeAmount === 0n && BigInt(p.params.withdrawalAddress) === BigInt(identity);
|
|
3258
3390
|
const authority = identity && !unsignedSweep ? await this.authority("transact", n.capacity, words, p.authorization, identity) : zeroAuthority();
|
|
3259
3391
|
const sources = await this.noteInputs(
|
|
3260
3392
|
p.inputs,
|
|
@@ -3263,22 +3395,44 @@ var WitnessBuilder = class {
|
|
|
3263
3395
|
identity ?? "0x" + "00".repeat(32),
|
|
3264
3396
|
authority
|
|
3265
3397
|
);
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
"output
|
|
3270
|
-
|
|
3271
|
-
|
|
3398
|
+
const outputs = await Promise.all(
|
|
3399
|
+
p.outputs.map(async (output, i) => {
|
|
3400
|
+
const opening = "identity" in output ? output.note : output;
|
|
3401
|
+
const identity2 = "identity" in output ? field(output.identity) : BigInt(
|
|
3402
|
+
await computeNoteIdentity2(BigInt(output.ownerAddress), output.nonce)
|
|
3403
|
+
);
|
|
3404
|
+
const amount = uint(output.amount, 128, "output amount");
|
|
3405
|
+
check2(identity2 !== 0n && amount !== 0n, "zero output identity or amount");
|
|
3406
|
+
if (opening) {
|
|
3407
|
+
this.context(opening);
|
|
3408
|
+
check2(
|
|
3409
|
+
opening.amount === amount && BigInt(
|
|
3410
|
+
await computeNoteIdentity2(
|
|
3411
|
+
BigInt(opening.ownerAddress),
|
|
3412
|
+
opening.nonce
|
|
3413
|
+
)
|
|
3414
|
+
) === identity2,
|
|
3415
|
+
"output opening mismatch"
|
|
3416
|
+
);
|
|
3417
|
+
}
|
|
3418
|
+
const commitment = await computeNoteCommitment3(
|
|
3419
|
+
c.chainId,
|
|
3420
|
+
word(identity2),
|
|
3421
|
+
BigInt(c.tokenAddress),
|
|
3422
|
+
amount
|
|
3423
|
+
);
|
|
3424
|
+
check2(commitment === p.params.outputCommitments[i], "output commitment mismatch");
|
|
3425
|
+
return { identity: identity2, amount };
|
|
3426
|
+
})
|
|
3427
|
+
);
|
|
3428
|
+
const all = [...p.inputs.map((input) => input.note), ...outputs];
|
|
3272
3429
|
return provingRequest(
|
|
3273
3430
|
`transact_user_slots${n.capacity}`,
|
|
3274
3431
|
{
|
|
3275
|
-
|
|
3432
|
+
input_owner_address: identity ? BigInt(identity) : 0n,
|
|
3276
3433
|
...authority,
|
|
3277
|
-
|
|
3278
|
-
[
|
|
3279
|
-
...p.inputs.map(() => 0n),
|
|
3280
|
-
...p.outputs.map((note) => BigInt(note.walletIdentity))
|
|
3281
|
-
],
|
|
3434
|
+
output_identities: pad2(
|
|
3435
|
+
[...p.inputs.map(() => 0n), ...outputs.map((output) => output.identity)],
|
|
3282
3436
|
n.capacity,
|
|
3283
3437
|
() => 0n
|
|
3284
3438
|
),
|
|
@@ -3288,7 +3442,7 @@ var WitnessBuilder = class {
|
|
|
3288
3442
|
() => 0n
|
|
3289
3443
|
),
|
|
3290
3444
|
nonces: pad2(
|
|
3291
|
-
|
|
3445
|
+
[...p.inputs.map((input) => input.note.nonce), ...outputs.map(() => 0n)],
|
|
3292
3446
|
n.capacity,
|
|
3293
3447
|
() => 0n
|
|
3294
3448
|
),
|
|
@@ -3332,7 +3486,7 @@ var WitnessBuilder = class {
|
|
|
3332
3486
|
);
|
|
3333
3487
|
if (p.change)
|
|
3334
3488
|
check2(
|
|
3335
|
-
p.change.
|
|
3489
|
+
p.change.ownerAddress === note.ownerWalletIdentity && await this.noteLeaf(p.change) === p.params.changeCommitment,
|
|
3336
3490
|
"change commitment mismatch"
|
|
3337
3491
|
);
|
|
3338
3492
|
else check2(BigInt(p.params.changeCommitment) === 0n, "missing change note");
|
|
@@ -3551,14 +3705,14 @@ var WitnessBuilder = class {
|
|
|
3551
3705
|
};
|
|
3552
3706
|
|
|
3553
3707
|
// src/factory.ts
|
|
3554
|
-
import { Contract as Contract3, getAddress as
|
|
3708
|
+
import { Contract as Contract3, getAddress as getAddress9 } from "ethers";
|
|
3555
3709
|
async function resolveInstanceAddress(client, factoryAddress, salt) {
|
|
3556
3710
|
const instance = await new Contract3(
|
|
3557
|
-
|
|
3711
|
+
getAddress9(factoryAddress),
|
|
3558
3712
|
invisiFactoryAbi,
|
|
3559
3713
|
client
|
|
3560
3714
|
).getFunction("getInstanceAddress")(salt);
|
|
3561
|
-
return
|
|
3715
|
+
return getAddress9(instance);
|
|
3562
3716
|
}
|
|
3563
3717
|
export {
|
|
3564
3718
|
AddressRegistry,
|