@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.
Files changed (118) hide show
  1. package/README.md +5 -0
  2. package/dist/broadcaster-3KTB4JO2.cjs +21 -0
  3. package/dist/broadcaster-3KTB4JO2.cjs.map +1 -0
  4. package/dist/broadcaster-7ZKKSTZQ.js +21 -0
  5. package/dist/broadcaster-preparation-PJ263WBL.cjs +15 -0
  6. package/dist/broadcaster-preparation-PJ263WBL.cjs.map +1 -0
  7. package/dist/broadcaster-preparation-ZQAPZAUG.js +15 -0
  8. package/dist/broadcaster-preparation-ZQAPZAUG.js.map +1 -0
  9. package/dist/{chunk-LOU7AP2B.cjs → chunk-2URICDPW.cjs} +72 -33
  10. package/dist/chunk-2URICDPW.cjs.map +1 -0
  11. package/dist/chunk-3D24ABYR.js +86 -0
  12. package/dist/chunk-3D24ABYR.js.map +1 -0
  13. package/dist/chunk-3KTQQZOW.cjs +71 -0
  14. package/dist/chunk-3KTQQZOW.cjs.map +1 -0
  15. package/dist/chunk-4SDP53YQ.cjs +765 -0
  16. package/dist/chunk-4SDP53YQ.cjs.map +1 -0
  17. package/dist/{chunk-XHKQ2BO2.js → chunk-4VI6LYGH.js} +25 -2
  18. package/dist/chunk-4VI6LYGH.js.map +1 -0
  19. package/dist/chunk-BBSRP4MH.cjs +287 -0
  20. package/dist/chunk-BBSRP4MH.cjs.map +1 -0
  21. package/dist/chunk-DGMVGFKM.js +41 -0
  22. package/dist/chunk-DGMVGFKM.js.map +1 -0
  23. package/dist/chunk-DHQEB6JR.cjs +1616 -0
  24. package/dist/chunk-DHQEB6JR.cjs.map +1 -0
  25. package/dist/chunk-FKF67XE6.js +1616 -0
  26. package/dist/chunk-FKF67XE6.js.map +1 -0
  27. package/dist/chunk-GUD3LAUO.js +765 -0
  28. package/dist/chunk-GUD3LAUO.js.map +1 -0
  29. package/dist/chunk-HCB7RQ3S.cjs +79 -0
  30. package/dist/chunk-HCB7RQ3S.cjs.map +1 -0
  31. package/dist/{chunk-GTPUYPQL.js → chunk-HKGJXQVN.js} +69 -30
  32. package/dist/chunk-HKGJXQVN.js.map +1 -0
  33. package/dist/chunk-HLH5JZD4.js +287 -0
  34. package/dist/chunk-HLH5JZD4.js.map +1 -0
  35. package/dist/chunk-J6TZZVAM.cjs +230 -0
  36. package/dist/chunk-J6TZZVAM.cjs.map +1 -0
  37. package/dist/{chunk-7F7ZZW3L.cjs → chunk-LOR6PYH5.cjs} +25 -2
  38. package/dist/chunk-LOR6PYH5.cjs.map +1 -0
  39. package/dist/chunk-MA2QZEF5.cjs +399 -0
  40. package/dist/chunk-MA2QZEF5.cjs.map +1 -0
  41. package/dist/chunk-MI4IP4ZD.cjs +86 -0
  42. package/dist/chunk-MI4IP4ZD.cjs.map +1 -0
  43. package/dist/chunk-OCZLJKIA.cjs +41 -0
  44. package/dist/chunk-OCZLJKIA.cjs.map +1 -0
  45. package/dist/chunk-R5YAOJKB.js +71 -0
  46. package/dist/chunk-R5YAOJKB.js.map +1 -0
  47. package/dist/chunk-RY4M2CIQ.js +399 -0
  48. package/dist/chunk-RY4M2CIQ.js.map +1 -0
  49. package/dist/chunk-THMD5QO2.js +79 -0
  50. package/dist/chunk-THMD5QO2.js.map +1 -0
  51. package/dist/chunk-ZD2652WH.js +230 -0
  52. package/dist/chunk-ZD2652WH.js.map +1 -0
  53. package/dist/credit.cjs +1 -0
  54. package/dist/credit.cjs.map +1 -0
  55. package/dist/credit.d.cts +12 -0
  56. package/dist/credit.d.ts +12 -0
  57. package/dist/credit.js +1 -0
  58. package/dist/credit.js.map +1 -0
  59. package/dist/ethers.cjs +2 -2
  60. package/dist/ethers.cjs.map +1 -1
  61. package/dist/ethers.d.cts +15 -4
  62. package/dist/ethers.d.ts +15 -4
  63. package/dist/ethers.js +1 -1
  64. package/dist/index-CLhGwLxZ.d.cts +42 -0
  65. package/dist/index-Crp-ZFiM.d.ts +42 -0
  66. package/dist/index.cjs +69 -38
  67. package/dist/index.cjs.map +1 -1
  68. package/dist/index.d.cts +21 -14
  69. package/dist/index.d.ts +21 -14
  70. package/dist/index.js +64 -33
  71. package/dist/index.js.map +1 -1
  72. package/dist/note.cjs +11 -0
  73. package/dist/note.cjs.map +1 -0
  74. package/dist/note.d.cts +29 -0
  75. package/dist/note.d.ts +29 -0
  76. package/dist/note.js +11 -0
  77. package/dist/note.js.map +1 -0
  78. package/dist/{broadcaster-preparation-DMxxZ_1Q.d.cts → operation-bridge-CoECSxfi.d.cts} +130 -245
  79. package/dist/{broadcaster-preparation-DMxxZ_1Q.d.ts → operation-bridge-CoECSxfi.d.ts} +130 -245
  80. package/dist/preparation-HUBTVCZE.js +404 -0
  81. package/dist/preparation-HUBTVCZE.js.map +1 -0
  82. package/dist/preparation-QD3ZSYV5.cjs +404 -0
  83. package/dist/preparation-QD3ZSYV5.cjs.map +1 -0
  84. package/dist/provenance-preparation-43DN2WK7.cjs +16 -0
  85. package/dist/provenance-preparation-43DN2WK7.cjs.map +1 -0
  86. package/dist/provenance-preparation-HEZE4L5H.js +16 -0
  87. package/dist/provenance-preparation-HEZE4L5H.js.map +1 -0
  88. package/dist/provenance.cjs +59 -0
  89. package/dist/provenance.cjs.map +1 -0
  90. package/dist/provenance.d.cts +34 -0
  91. package/dist/provenance.d.ts +34 -0
  92. package/dist/provenance.js +59 -0
  93. package/dist/provenance.js.map +1 -0
  94. package/dist/{receipt-logs-m0-bhaxW.d.ts → receipt-logs-DQRJK0l8.d.cts} +84 -78
  95. package/dist/{receipt-logs-CvC951p7.d.cts → receipt-logs-fMR6Bwql.d.ts} +84 -78
  96. package/dist/session-support.cjs +28 -7
  97. package/dist/session-support.cjs.map +1 -1
  98. package/dist/session-support.d.cts +71 -39
  99. package/dist/session-support.d.ts +71 -39
  100. package/dist/session-support.js +58 -37
  101. package/dist/session-support.js.map +1 -1
  102. package/package.json +22 -6
  103. package/dist/broadcaster-preparation-RMWQFYNL.js +0 -11
  104. package/dist/broadcaster-preparation-UGOTO4SX.cjs +0 -11
  105. package/dist/broadcaster-preparation-UGOTO4SX.cjs.map +0 -1
  106. package/dist/chunk-7F7ZZW3L.cjs.map +0 -1
  107. package/dist/chunk-EHP5TBC6.js +0 -3565
  108. package/dist/chunk-EHP5TBC6.js.map +0 -1
  109. package/dist/chunk-GTPUYPQL.js.map +0 -1
  110. package/dist/chunk-ITTGBIG2.js +0 -1877
  111. package/dist/chunk-ITTGBIG2.js.map +0 -1
  112. package/dist/chunk-J2JH6HIG.cjs +0 -1877
  113. package/dist/chunk-J2JH6HIG.cjs.map +0 -1
  114. package/dist/chunk-LOU7AP2B.cjs.map +0 -1
  115. package/dist/chunk-RHNIHI4P.cjs +0 -3565
  116. package/dist/chunk-RHNIHI4P.cjs.map +0 -1
  117. package/dist/chunk-XHKQ2BO2.js.map +0 -1
  118. /package/dist/{broadcaster-preparation-RMWQFYNL.js.map → broadcaster-7ZKKSTZQ.js.map} +0 -0
@@ -0,0 +1,765 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return 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; }// src/payment-note/codec.ts
2
+ var _primitives = require('@invisi-labs/primitives');
3
+ var _ethers = require('ethers');
4
+ function uint(value, bytes) {
5
+ if (typeof value !== "bigint" || value < 0n || value >= 1n << BigInt(bytes * 8))
6
+ throw new RangeError(`Invalid uint${bytes * 8} payment note field`);
7
+ return _ethers.getBytes.call(void 0, `0x${value.toString(16).padStart(bytes * 2, "0")}`);
8
+ }
9
+ function validate(value) {
10
+ const keys = [
11
+ "chainId",
12
+ "protocolAddress",
13
+ "tokenAddress",
14
+ "amount",
15
+ "ownerAddress",
16
+ "nonce",
17
+ "commitment"
18
+ ];
19
+ if (!value || typeof value !== "object" || Object.keys(value).some((key) => !keys.includes(key)))
20
+ throw new TypeError("Invalid payment note fields");
21
+ uint(value.chainId, 8);
22
+ uint(value.amount, 16);
23
+ if (value.chainId === 0n || value.amount === 0n)
24
+ throw new RangeError("Positive chainId and amount required");
25
+ for (const key of ["protocolAddress", "ownerAddress", "tokenAddress"]) {
26
+ _ethers.getAddress.call(void 0, value[key]);
27
+ if (key !== "tokenAddress" && BigInt(value[key]) === 0n)
28
+ throw new RangeError(`Invalid ${key}`);
29
+ }
30
+ uint(value.nonce, 32);
31
+ if (value.nonce >= _primitives.FIELD_MODULUS) throw new RangeError("Invalid payment note nonce");
32
+ if (!/^0x[\da-f]{64}$/i.test(value.commitment) || BigInt(value.commitment) <= 0n || BigInt(value.commitment) >= _primitives.FIELD_MODULUS)
33
+ throw new RangeError("Invalid payment note commitment");
34
+ }
35
+ function encodePaymentNote(value) {
36
+ validate(value);
37
+ const bytes = _ethers.concat.call(void 0, [
38
+ new Uint8Array([1]),
39
+ uint(value.chainId, 8),
40
+ _ethers.getBytes.call(void 0, value.protocolAddress),
41
+ _ethers.getBytes.call(void 0, value.tokenAddress),
42
+ uint(value.amount, 16),
43
+ _ethers.getBytes.call(void 0, value.ownerAddress),
44
+ uint(value.nonce, 32),
45
+ _ethers.getBytes.call(void 0, value.commitment)
46
+ ]);
47
+ return `ipn:${_ethers.encodeBase64.call(void 0, bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")}`;
48
+ }
49
+ function decodePaymentNote(encoded) {
50
+ if (typeof encoded !== "string" || encoded.length !== 203 || !/^ipn:[A-Za-z0-9_-]+$/.test(encoded))
51
+ throw new TypeError("Invalid payment note encoding");
52
+ const bytes = _ethers.decodeBase64.call(void 0, encoded.slice(4).replace(/-/g, "+").replace(/_/g, "/") + "=");
53
+ if (bytes.length !== 149 || bytes[0] !== 1)
54
+ throw new Error("Unsupported payment note version or length");
55
+ let offset = 1;
56
+ const take = (size) => {
57
+ const value2 = _ethers.hexlify.call(void 0, bytes.slice(offset, offset += size));
58
+ return value2;
59
+ };
60
+ const value = {
61
+ chainId: BigInt(take(8)),
62
+ protocolAddress: _ethers.getAddress.call(void 0, take(20)),
63
+ tokenAddress: _ethers.getAddress.call(void 0, take(20)),
64
+ amount: BigInt(take(16)),
65
+ ownerAddress: _ethers.getAddress.call(void 0, take(20)).toLowerCase(),
66
+ nonce: BigInt(take(32)),
67
+ commitment: take(32)
68
+ };
69
+ if (encodePaymentNote(value) !== encoded) throw new Error("Noncanonical payment note encoding");
70
+ return value;
71
+ }
72
+
73
+ // src/errors.ts
74
+
75
+ var InvisiError = class extends Error {
76
+
77
+
78
+
79
+
80
+
81
+
82
+ constructor(code, message, details = {}) {
83
+ super(message, { cause: details.cause });
84
+ this.name = "InvisiError";
85
+ this.code = code;
86
+ this.operation = details.operation;
87
+ this.address = details.address;
88
+ this.outputIndex = details.outputIndex;
89
+ this.field = details.field;
90
+ this.capability = details.capability;
91
+ }
92
+ };
93
+ async function prepareWithErrors(operation, prepare) {
94
+ try {
95
+ return await prepare();
96
+ } catch (cause) {
97
+ if (cause instanceof InvisiError) {
98
+ if (cause.operation) throw cause;
99
+ throw new InvisiError(cause.code, cause.message, {
100
+ operation,
101
+ ...cause.address === void 0 ? {} : { address: cause.address },
102
+ ...cause.outputIndex === void 0 ? {} : { outputIndex: cause.outputIndex },
103
+ ...cause.field === void 0 ? {} : { field: cause.field },
104
+ ...cause.capability === void 0 ? {} : { capability: cause.capability },
105
+ cause: cause.cause
106
+ });
107
+ }
108
+ throw new InvisiError(
109
+ cause instanceof _primitives.MissingCapabilityError ? "MISSING_CAPABILITY" : "PREPARATION_FAILED",
110
+ cause instanceof Error ? cause.message : "Transaction preparation failed",
111
+ {
112
+ operation,
113
+ cause,
114
+ ...cause instanceof _primitives.MissingCapabilityError ? { capability: cause.capability } : {}
115
+ }
116
+ );
117
+ }
118
+ }
119
+
120
+ // src/notes/resolve-recipient.ts
121
+
122
+
123
+
124
+
125
+ async function resolveRecipient(address, lookup, details = {}) {
126
+ const context = { ...details, address };
127
+ let recipient;
128
+ try {
129
+ recipient = _primitives.ReceivingAddress.parse(address);
130
+ } catch (cause) {
131
+ throw new InvisiError("INVALID_RECIPIENT", "Invalid recipient address", {
132
+ ...context,
133
+ cause
134
+ });
135
+ }
136
+ if (recipient.kind === "long") return recipient;
137
+ if (!lookup) {
138
+ throw new InvisiError("MISSING_CAPABILITY", "Missing registry lookup capability", {
139
+ ...context,
140
+ capability: "registry lookup"
141
+ });
142
+ }
143
+ let keys;
144
+ try {
145
+ keys = await lookup(recipient.ownerAddress);
146
+ } catch (cause) {
147
+ if (cause instanceof _primitives.MissingCapabilityError) {
148
+ throw new InvisiError("MISSING_CAPABILITY", cause.message, {
149
+ ...context,
150
+ cause,
151
+ capability: cause.capability
152
+ });
153
+ }
154
+ throw new InvisiError("RECIPIENT_LOOKUP_FAILED", "Recipient registry lookup failed", {
155
+ ...context,
156
+ cause
157
+ });
158
+ }
159
+ if (keys == null) {
160
+ throw new InvisiError(
161
+ "EVM_ADDRESS_NOT_REGISTERED",
162
+ "EVM address has no registered receiving keys",
163
+ context
164
+ );
165
+ }
166
+ try {
167
+ return _primitives.ReceivingAddress.from({
168
+ ownerAddress: recipient.ownerAddress,
169
+ viewingPublicKey: keys.viewingPublicKey,
170
+ clueKey: keys.clueKey
171
+ });
172
+ } catch (cause) {
173
+ throw new InvisiError(
174
+ "RECIPIENT_LOOKUP_FAILED",
175
+ "Registry returned invalid receiving keys",
176
+ { ...context, cause }
177
+ );
178
+ }
179
+ }
180
+
181
+ // src/payment-request/codec.ts
182
+
183
+
184
+
185
+ // src/payment-request/binary.ts
186
+ function uint2(value, size, name) {
187
+ if (typeof value !== "bigint" || value < 0n || value >= 1n << BigInt(size * 8))
188
+ throw new RangeError(`${name} must be uint${size * 8}`);
189
+ const result = new Uint8Array(size);
190
+ for (let i = size - 1; i >= 0; i--) {
191
+ result[i] = Number(value & 255n);
192
+ value >>= 8n;
193
+ }
194
+ return result;
195
+ }
196
+ function concat2(parts) {
197
+ const result = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
198
+ let offset = 0;
199
+ for (const part of parts) {
200
+ result.set(part, offset);
201
+ offset += part.length;
202
+ }
203
+ return result;
204
+ }
205
+ var Reader = class {
206
+ constructor(data) {
207
+ this.data = data;
208
+ }
209
+ #offset = 0;
210
+ take(size) {
211
+ if (this.#offset + size > this.data.length) throw new Error("Truncated payment request");
212
+ const result = this.data.slice(this.#offset, this.#offset + size);
213
+ this.#offset += size;
214
+ return result;
215
+ }
216
+ integer(size) {
217
+ return this.take(size).reduce((n, b) => n << 8n | BigInt(b), 0n);
218
+ }
219
+ done() {
220
+ if (this.#offset !== this.data.length) throw new Error("Trailing payment request bytes");
221
+ }
222
+ };
223
+
224
+ // src/payment-request/validation.ts
225
+
226
+
227
+ var MAX_REQUEST_PAYLOAD_BYTES = _primitives.MAX_CIPHERTEXT_BYTES - 160;
228
+ function fields(value, allowed, name) {
229
+ if (!value || typeof value !== "object" || Array.isArray(value))
230
+ throw new TypeError(`Invalid ${name}`);
231
+ for (const key of Object.keys(value))
232
+ if (!allowed.includes(key)) throw new TypeError(`Unsupported ${name} field ${key}`);
233
+ }
234
+ function nonce(value) {
235
+ uint2(value, 32, "nonce");
236
+ if (value >= _primitives.FIELD_MODULUS)
237
+ throw new RangeError("nonce must be a canonical BN254 field element");
238
+ return value;
239
+ }
240
+ function validatePaymentRequest(request) {
241
+ fields(
242
+ request,
243
+ ["chainId", "protocolAddress", "tokenAddress", "amount", "recipient", "payload"],
244
+ "payment request"
245
+ );
246
+ uint2(request.chainId, 8, "chainId");
247
+ if (request.chainId === 0n) throw new RangeError("chainId must be positive");
248
+ const protocol = _ethers.getAddress.call(void 0, request.protocolAddress);
249
+ _ethers.getAddress.call(void 0, request.tokenAddress);
250
+ if (BigInt(protocol) === 0n) throw new RangeError("protocol address must be nonzero");
251
+ uint2(request.amount, 16, "amount");
252
+ if (request.amount === 0n) throw new RangeError("amount must be positive");
253
+ const recipient = request.recipient;
254
+ fields(
255
+ recipient,
256
+ ["type", "address", "nonce", "identity", "envelope", "addressLookup"],
257
+ "recipient"
258
+ );
259
+ if (recipient.type === "identity") {
260
+ fields(recipient, ["type", "identity"], "identity recipient");
261
+ if (typeof recipient.identity !== "string" || !/^0x[\da-f]{64}$/i.test(recipient.identity) || BigInt(recipient.identity) <= 0n || BigInt(recipient.identity) >= _primitives.FIELD_MODULUS)
262
+ throw new RangeError("identity must be a nonzero canonical BN254 field element");
263
+ if (request.payload !== void 0)
264
+ throw new TypeError("payload requires an encrypted envelope");
265
+ return;
266
+ }
267
+ if (recipient.type !== "evm" && recipient.type !== "invisi")
268
+ throw new TypeError("Invalid recipient type");
269
+ fields(
270
+ recipient,
271
+ recipient.type === "evm" ? ["type", "address", "nonce", "envelope", "addressLookup"] : ["type", "address", "nonce"],
272
+ "recipient"
273
+ );
274
+ const parsed = _primitives.ReceivingAddress.parse(recipient.address);
275
+ if (recipient.type === "evm" !== (parsed.kind === "short"))
276
+ throw new TypeError("recipient address type mismatch");
277
+ if (BigInt(parsed.ownerAddress) === 0n) throw new RangeError("owner address must be nonzero");
278
+ if (recipient.nonce !== void 0) nonce(recipient.nonce);
279
+ if (recipient.type === "evm") {
280
+ if (recipient.envelope !== void 0 && typeof recipient.envelope !== "boolean")
281
+ throw new TypeError("evm envelope must be boolean");
282
+ if (recipient.addressLookup !== void 0 && !["chain", "protocol-rpc"].includes(recipient.addressLookup))
283
+ throw new TypeError("Invalid recipient addressLookup");
284
+ if (recipient.envelope === false && request.payload !== void 0)
285
+ throw new TypeError("payload requires an encrypted envelope");
286
+ }
287
+ if (request.payload !== void 0 && !(request.payload instanceof Uint8Array))
288
+ throw new TypeError("payload must be Uint8Array");
289
+ if ((_nullishCoalesce(_optionalChain([request, 'access', _2 => _2.payload, 'optionalAccess', _3 => _3.length]), () => ( 0))) > MAX_REQUEST_PAYLOAD_BYTES)
290
+ throw new RangeError("payload exceeds funds envelope limit");
291
+ }
292
+
293
+ // src/payment-request/codec.ts
294
+ var PREFIX = "ipr:";
295
+ var VERSION = 1;
296
+ var MAX_BINARY_BYTES = 186 + MAX_REQUEST_PAYLOAD_BYTES;
297
+ function base64url(data) {
298
+ return _ethers.encodeBase64.call(void 0, data).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
299
+ }
300
+ function encodePaymentRequest(request) {
301
+ validatePaymentRequest(request);
302
+ const recipient = request.recipient;
303
+ const parts = [
304
+ new Uint8Array([
305
+ VERSION,
306
+ recipient.type === "evm" ? 1 : recipient.type === "invisi" ? 2 : 3
307
+ ]),
308
+ uint2(request.chainId, 8, "chainId"),
309
+ _ethers.getBytes.call(void 0, request.protocolAddress),
310
+ _ethers.getBytes.call(void 0, request.tokenAddress),
311
+ uint2(request.amount, 16, "amount")
312
+ ];
313
+ if (recipient.type === "identity") parts.push(_ethers.getBytes.call(void 0, recipient.identity));
314
+ else {
315
+ const parsed = _primitives.ReceivingAddress.parse(recipient.address);
316
+ parts.push(_ethers.getBytes.call(void 0, parsed.ownerAddress));
317
+ if (recipient.type === "invisi") {
318
+ const keys = parsed.getReceivingKeys();
319
+ parts.push(keys.viewingPublicKey, keys.clueKey);
320
+ } else parts.push(new Uint8Array([recipient.envelope === false ? 0 : 1]));
321
+ parts.push(new Uint8Array([recipient.nonce === void 0 ? 0 : 1]));
322
+ if (recipient.nonce !== void 0) parts.push(uint2(recipient.nonce, 32, "nonce"));
323
+ if (recipient.type === "invisi" || recipient.envelope !== false) {
324
+ const payload = _nullishCoalesce(request.payload, () => ( new Uint8Array()));
325
+ parts.push(uint2(BigInt(payload.length), 2, "payloadLength"), payload);
326
+ }
327
+ }
328
+ return PREFIX + base64url(concat2(parts));
329
+ }
330
+ function decodePaymentRequest(encoded) {
331
+ if (typeof encoded !== "string" || !encoded.startsWith(PREFIX) || encoded.length > 4 + Math.ceil(MAX_BINARY_BYTES * 8 / 6))
332
+ throw new Error("Invalid payment request encoding");
333
+ const text = encoded.slice(PREFIX.length);
334
+ if (!/^[A-Za-z0-9_-]+$/.test(text) || text.length % 4 === 1)
335
+ throw new Error("Invalid payment request Base64URL");
336
+ const data = _ethers.decodeBase64.call(void 0,
337
+ text.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - text.length % 4) % 4)
338
+ );
339
+ if (base64url(data) !== text) throw new Error("Noncanonical payment request Base64URL");
340
+ const reader = new Reader(data);
341
+ if (reader.integer(1) !== BigInt(VERSION))
342
+ throw new Error("Unsupported payment request version");
343
+ const type = reader.integer(1);
344
+ if (type < 1n || type > 3n) throw new Error("Unsupported payment request recipient type");
345
+ const context = {
346
+ chainId: reader.integer(8),
347
+ protocolAddress: _ethers.hexlify.call(void 0, reader.take(20)),
348
+ tokenAddress: _ethers.hexlify.call(void 0, reader.take(20)),
349
+ amount: reader.integer(16)
350
+ };
351
+ let recipient;
352
+ let payload;
353
+ if (type === 3n)
354
+ recipient = { type: "identity", identity: _ethers.hexlify.call(void 0, reader.take(32)) };
355
+ else {
356
+ const ownerAddress = _ethers.hexlify.call(void 0, reader.take(20));
357
+ let address;
358
+ let envelope = true;
359
+ if (type === 2n)
360
+ address = _primitives.ReceivingAddress.from({
361
+ ownerAddress,
362
+ viewingPublicKey: reader.take(33),
363
+ clueKey: reader.take(32)
364
+ }).toString();
365
+ else {
366
+ address = _primitives.ReceivingAddress.fromIdentity(ownerAddress).toString();
367
+ const value = reader.integer(1);
368
+ if (value > 1n) throw new Error("Invalid envelope flag");
369
+ envelope = value === 1n;
370
+ }
371
+ const present = reader.integer(1);
372
+ if (present > 1n) throw new Error("Invalid nonce presence flag");
373
+ const nonce2 = present === 1n ? reader.integer(32) : void 0;
374
+ recipient = type === 2n ? { type: "invisi", address, ...nonce2 === void 0 ? {} : { nonce: nonce2 } } : { type: "evm", address, envelope, ...nonce2 === void 0 ? {} : { nonce: nonce2 } };
375
+ if (envelope) {
376
+ const length = Number(reader.integer(2));
377
+ if (length > MAX_REQUEST_PAYLOAD_BYTES)
378
+ throw new RangeError("payload exceeds funds envelope limit");
379
+ if (length !== 0) payload = reader.take(length);
380
+ }
381
+ }
382
+ reader.done();
383
+ const request = {
384
+ ...context,
385
+ recipient,
386
+ ...payload === void 0 ? {} : { payload }
387
+ };
388
+ validatePaymentRequest(request);
389
+ if (encodePaymentRequest(request) !== encoded) throw new Error("Noncanonical payment request");
390
+ return request;
391
+ }
392
+
393
+ // src/payment-note/export.ts
394
+ function exportPaymentNote(output) {
395
+ const note = output.note;
396
+ if (output.recipient.type === "identity" || !note)
397
+ throw new Error("Identity outputs cannot export an IPN");
398
+ return encodePaymentNote({
399
+ chainId: note.chainId,
400
+ protocolAddress: output.context.protocolAddress,
401
+ tokenAddress: output.context.tokenAddress,
402
+ amount: note.amount,
403
+ ownerAddress: note.ownerAddress,
404
+ nonce: note.nonce,
405
+ commitment: output.commitment
406
+ });
407
+ }
408
+
409
+ // src/notes/NoteOutput.ts
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+ // src/payment-request/match-output.ts
422
+
423
+
424
+ function assertRequestMatchesOutput(ipp, output) {
425
+ const request = decodePaymentRequest(ipp);
426
+ const expected = request.recipient;
427
+ const actual = output.recipient;
428
+ if (request.chainId !== output.context.chainId || BigInt(request.protocolAddress) !== BigInt(output.context.protocolAddress) || BigInt(request.tokenAddress) !== BigInt(output.context.tokenAddress) || request.amount !== output.amount || expected.type !== actual.type)
429
+ throw new Error("IPR does not match output context or recipient");
430
+ if (expected.type === "identity") {
431
+ if (actual.type !== "identity" || BigInt(expected.identity) !== BigInt(actual.identity))
432
+ throw new Error("IPR identity mismatch");
433
+ return;
434
+ }
435
+ if (actual.type === "identity") throw new Error("IPR recipient type mismatch");
436
+ const parsed = _primitives.ReceivingAddress.parse(expected.address);
437
+ const resolved = _primitives.ReceivingAddress.parse(actual.address);
438
+ if (parsed.ownerAddress !== resolved.ownerAddress || expected.nonce !== void 0 && expected.nonce !== _optionalChain([output, 'access', _4 => _4.note, 'optionalAccess', _5 => _5.nonce]) || _ethers.hexlify.call(void 0, _nullishCoalesce(request.payload, () => ( new Uint8Array()))) !== _ethers.hexlify.call(void 0, _nullishCoalesce(_optionalChain([output, 'access', _6 => _6.note, 'optionalAccess', _7 => _7.payload]), () => ( new Uint8Array()))))
439
+ throw new Error("IPR does not match output opening");
440
+ if (expected.type === "evm" && actual.type === "evm" && expected.envelope !== false !== (actual.envelope !== false))
441
+ throw new Error("IPR envelope mismatch");
442
+ if (expected.type === "invisi") {
443
+ const a = parsed.getReceivingKeys(), b = resolved.getReceivingKeys();
444
+ if (_ethers.hexlify.call(void 0, a.viewingPublicKey) !== _ethers.hexlify.call(void 0, b.viewingPublicKey) || _ethers.hexlify.call(void 0, a.clueKey) !== _ethers.hexlify.call(void 0, b.clueKey))
445
+ throw new Error("IPR receiving keys mismatch");
446
+ }
447
+ }
448
+
449
+ // src/payment-request/execution.ts
450
+ function applyExecutionOptions(request, execution) {
451
+ fields(execution, ["nonce", "addressLookup"], "execution options");
452
+ const copy = structuredClone(request);
453
+ const recipient = copy.recipient;
454
+ if (execution.nonce !== void 0) {
455
+ if (recipient.type === "identity")
456
+ throw new TypeError("identity recipient cannot specify nonce");
457
+ nonce(execution.nonce);
458
+ if (recipient.nonce !== void 0 && recipient.nonce !== execution.nonce)
459
+ throw new Error("nonce conflicts with the fixed payment request");
460
+ recipient.nonce = execution.nonce;
461
+ }
462
+ if (execution.addressLookup !== void 0) {
463
+ if (recipient.type !== "evm" || recipient.envelope === false)
464
+ throw new TypeError("addressLookup requires an encrypted EVM recipient");
465
+ if (!["chain", "protocol-rpc"].includes(execution.addressLookup))
466
+ throw new TypeError("Invalid addressLookup");
467
+ recipient.addressLookup = execution.addressLookup;
468
+ }
469
+ return copy;
470
+ }
471
+
472
+ // src/notes/NoteOutput.ts
473
+ function nonceValue(value) {
474
+ if (typeof value !== "bigint" || value < 0n || value >= _primitives.FIELD_MODULUS)
475
+ throw new RangeError("nonce must be a canonical BN254 field element");
476
+ return value;
477
+ }
478
+ function identityValue(value) {
479
+ if (typeof value !== "string" || !/^0x[0-9a-fA-F]{64}$/.test(value) || BigInt(value) <= 0n || BigInt(value) >= _primitives.FIELD_MODULUS)
480
+ throw new RangeError("identity must be a nonzero canonical BN254 field element");
481
+ return value.toLowerCase();
482
+ }
483
+ function payloadCopy(value) {
484
+ if (value === void 0) return new Uint8Array();
485
+ if (!(value instanceof Uint8Array)) throw new TypeError("payload must be Uint8Array");
486
+ return Uint8Array.from(value);
487
+ }
488
+ function fingerprint(delivery) {
489
+ return _ethers.keccak256.call(void 0,
490
+ _ethers.AbiCoder.defaultAbiCoder().encode(["bytes", "bytes"], [delivery.ciphertext, delivery.clue])
491
+ );
492
+ }
493
+ function checkedContext(context) {
494
+ if (typeof context.chainId !== "bigint" || context.chainId <= 0n)
495
+ throw new RangeError("chainId must be positive");
496
+ const protocolAddress = _ethers.getAddress.call(void 0, context.protocolAddress);
497
+ const tokenAddress = _ethers.getAddress.call(void 0, context.tokenAddress);
498
+ if (BigInt(protocolAddress) === 0n) throw new RangeError("protocol address must be nonzero");
499
+ return { chainId: context.chainId, protocolAddress, tokenAddress };
500
+ }
501
+ function encrypted(recipient) {
502
+ return recipient.type === "invisi" || recipient.type === "evm" && recipient.envelope !== false;
503
+ }
504
+ function rejectLegacy(value) {
505
+ for (const key of [
506
+ "expectedCommitment",
507
+ "nonce",
508
+ "envelope",
509
+ "context",
510
+ "to",
511
+ "addressResolver",
512
+ "addressLookup"
513
+ ])
514
+ if (key in value) throw new TypeError(`${key} is not a NoteOutput create option`);
515
+ }
516
+ var outputCreation = /* @__PURE__ */ Symbol("NoteOutput.create");
517
+ var NoteOutput = class _NoteOutput {
518
+
519
+
520
+
521
+
522
+
523
+
524
+ /** Encrypted EVM delivery is resolved by preparation; the original offline intent stays pending. */
525
+
526
+ constructor(output, token, ipp) {
527
+ if (token !== outputCreation)
528
+ throw new TypeError("outputs must be created with NoteOutput.create");
529
+ const saved = structuredClone(output);
530
+ this.ipp = ipp;
531
+ this.to = saved.address;
532
+ this.amount = saved.amount;
533
+ this.identity = saved.identity;
534
+ this.commitment = saved.commitment;
535
+ this.deliveryFingerprint = fingerprint(saved.delivery);
536
+ this.deliveryPending = saved.deliveryPending === true;
537
+ Object.defineProperties(this, {
538
+ context: { enumerable: true, get: () => structuredClone(saved.context) },
539
+ recipient: { enumerable: true, get: () => structuredClone(saved.recipient) },
540
+ nonce: { enumerable: true, get: () => _optionalChain([saved, 'access', _8 => _8.note, 'optionalAccess', _9 => _9.nonce]) },
541
+ payload: { enumerable: true, get: () => payloadCopy(_optionalChain([saved, 'access', _10 => _10.note, 'optionalAccess', _11 => _11.payload])) },
542
+ preparedOutput: { enumerable: true, get: () => structuredClone(saved) }
543
+ });
544
+ Object.freeze(this);
545
+ }
546
+ /** Private offline delivery data; does not assert that the output has been mined. */
547
+ exportPaymentNote() {
548
+ return exportPaymentNote(this.preparedOutput);
549
+ }
550
+ static async create(input, execution = {}) {
551
+ if (typeof input !== "string") rejectLegacy(input);
552
+ const request = typeof input === "string" ? decodePaymentRequest(input) : structuredClone(input);
553
+ rejectLegacy(request);
554
+ const options = applyExecutionOptions(request, execution);
555
+ if (typeof options.amount !== "bigint" || options.amount <= 0n || options.amount >= 1n << 128n)
556
+ throw new RangeError("amount must be a positive uint128");
557
+ const context = checkedContext(options);
558
+ const recipient = structuredClone(options.recipient);
559
+ if (!recipient || !["evm", "invisi", "identity"].includes(recipient.type))
560
+ throw new TypeError("invalid recipient type");
561
+ if ("expectedCommitment" in recipient)
562
+ throw new TypeError("expectedCommitment is not supported");
563
+ const envelope = encrypted(recipient);
564
+ if (!envelope && options.payload !== void 0)
565
+ throw new TypeError("payload requires an encrypted envelope");
566
+ let identity;
567
+ let note;
568
+ let resolved;
569
+ let address;
570
+ if (recipient.type === "identity") {
571
+ if ("nonce" in recipient || "envelope" in recipient || "addressLookup" in recipient)
572
+ throw new TypeError("identity recipient cannot specify nonce or envelope");
573
+ identity = identityValue(recipient.identity);
574
+ address = identity;
575
+ } else {
576
+ if (recipient.type === "evm" && recipient.envelope !== void 0 && typeof recipient.envelope !== "boolean")
577
+ throw new TypeError("evm envelope must be boolean");
578
+ if (recipient.type === "invisi" && "envelope" in recipient)
579
+ throw new TypeError("invisi recipient is always encrypted");
580
+ let parsed;
581
+ try {
582
+ parsed = _primitives.ReceivingAddress.parse(recipient.address);
583
+ } catch (cause) {
584
+ throw new InvisiError("INVALID_RECIPIENT", "Invalid recipient address", {
585
+ address: recipient.address,
586
+ field: "to",
587
+ cause
588
+ });
589
+ }
590
+ if (recipient.type === "evm" !== (parsed.kind === "short"))
591
+ throw new TypeError("recipient address type mismatch");
592
+ resolved = parsed;
593
+ if (recipient.type === "evm") {
594
+ if (recipient.addressLookup !== void 0 && recipient.addressLookup !== "chain" && recipient.addressLookup !== "protocol-rpc")
595
+ throw new TypeError("invalid recipient addressLookup");
596
+ recipient.addressLookup ??= "protocol-rpc";
597
+ } else if ("addressLookup" in recipient)
598
+ throw new TypeError("addressLookup only applies to EVM recipients");
599
+ const nonce2 = nonceValue(
600
+ recipient.nonce === void 0 ? _primitives.generateNonce.call(void 0, ) : recipient.nonce
601
+ );
602
+ recipient.nonce = nonce2;
603
+ identity = await _primitives.computeNoteIdentity.call(void 0, BigInt(resolved.ownerAddress), nonce2);
604
+ address = recipient.address;
605
+ note = {
606
+ chainId: context.chainId,
607
+ protocolAddress: BigInt(context.protocolAddress),
608
+ tokenAddress: BigInt(context.tokenAddress),
609
+ ownerAddress: resolved.ownerAddress,
610
+ amount: options.amount,
611
+ nonce: nonce2,
612
+ payload: payloadCopy(options.payload)
613
+ };
614
+ }
615
+ const commitment = await _primitives.computeNoteCommitment.call(void 0,
616
+ context.chainId,
617
+ BigInt(context.protocolAddress),
618
+ identity,
619
+ BigInt(context.tokenAddress),
620
+ options.amount
621
+ );
622
+ let delivery = { ciphertext: "0x", clue: "0x" };
623
+ if (envelope && recipient.type === "invisi") {
624
+ const keys = resolved.getReceivingKeys();
625
+ delivery = {
626
+ ciphertext: _ethers.hexlify.call(void 0,
627
+ await _primitives.encryptPrivateTransferNote.call(void 0, keys.viewingPublicKey, note, {
628
+ chainId: context.chainId,
629
+ protocolAddress: BigInt(context.protocolAddress),
630
+ outputCommitment: commitment
631
+ })
632
+ ),
633
+ clue: _ethers.hexlify.call(void 0, _primitives.createClue.call(void 0, keys.clueKey))
634
+ };
635
+ }
636
+ const ipp = typeof input === "string" ? input : encodePaymentRequest(request);
637
+ return new _NoteOutput(
638
+ {
639
+ context,
640
+ recipient,
641
+ amount: options.amount,
642
+ ...note ? { note } : {},
643
+ identity,
644
+ commitment,
645
+ delivery,
646
+ ...envelope && recipient.type === "evm" ? { deliveryPending: true } : {},
647
+ address,
648
+ change: false
649
+ },
650
+ outputCreation,
651
+ ipp
652
+ );
653
+ }
654
+ assertCommitment(expectedHex) {
655
+ if (typeof expectedHex !== "string" || expectedHex.toLowerCase() !== this.commitment.toLowerCase())
656
+ throw new Error("note output commitment mismatch");
657
+ }
658
+ get note() {
659
+ return this.preparedOutput.note;
660
+ }
661
+ get delivery() {
662
+ return this.preparedOutput.delivery;
663
+ }
664
+ };
665
+ async function materializeNoteOutput(payment, context, lookup) {
666
+ if ("expectedCommitment" in payment) throw new TypeError("expectedCommitment is not supported");
667
+ const cached = payment.preparedOutput;
668
+ if (cached === void 0) throw new TypeError("outputs must be created with NoteOutput.create");
669
+ const output = structuredClone(cached);
670
+ const expectedContext = checkedContext(context);
671
+ const copied = payment;
672
+ for (const actual of [output.context, copied.context]) {
673
+ if (!actual || actual.chainId !== expectedContext.chainId || BigInt(actual.protocolAddress) !== BigInt(expectedContext.protocolAddress) || BigInt(actual.tokenAddress) !== BigInt(expectedContext.tokenAddress))
674
+ throw new Error("note output chain, protocol or token mismatch");
675
+ }
676
+ if (output.amount !== payment.amount || output.address !== payment.to || output.identity !== copied.identity || output.commitment !== copied.commitment || JSON.stringify(output.recipient, (_, v) => typeof v === "bigint" ? v.toString() : v) !== JSON.stringify(copied.recipient, (_, v) => typeof v === "bigint" ? v.toString() : v))
677
+ throw new Error("note output material does not match payment intent");
678
+ if (fingerprint(output.delivery) !== copied.deliveryFingerprint)
679
+ throw new Error("note output delivery fingerprint mismatch");
680
+ const hasCiphertext = output.delivery.ciphertext !== "0x";
681
+ const hasClue = output.delivery.clue !== "0x";
682
+ const pending = output.deliveryPending === true;
683
+ if (copied.deliveryPending !== pending || "deliveryPending" in output && output.deliveryPending !== true)
684
+ throw new Error("note output pending delivery mismatch");
685
+ if (hasCiphertext !== hasClue || (pending ? hasCiphertext || output.recipient.type !== "evm" || !encrypted(output.recipient) : hasCiphertext !== encrypted(output.recipient)))
686
+ throw new Error("note output delivery mode mismatch");
687
+ const recipient = output.recipient;
688
+ if ("expectedCommitment" in recipient) throw new Error("expectedCommitment is not supported");
689
+ if (!encrypted(recipient) && payloadCopy(payment.payload).length !== 0)
690
+ throw new Error("payload requires an encrypted envelope");
691
+ if (recipient.type === "identity") {
692
+ if (!/^0x[0-9a-fA-F]{64}$/.test(output.identity) || output.address !== output.identity || output.note || "nonce" in recipient || "envelope" in recipient || "addressLookup" in recipient || recipient.identity.toLowerCase() !== output.identity.toLowerCase())
693
+ throw new Error("opaque identity output material mismatch");
694
+ identityValue(output.identity);
695
+ } else {
696
+ const note = output.note;
697
+ const parsed = _primitives.ReceivingAddress.parse(recipient.address);
698
+ if (recipient.type === "evm" && recipient.addressLookup !== void 0 && recipient.addressLookup !== "chain" && recipient.addressLookup !== "protocol-rpc")
699
+ throw new Error("invalid recipient addressLookup");
700
+ if (recipient.type === "invisi" && "addressLookup" in recipient)
701
+ throw new Error("addressLookup only applies to EVM recipients");
702
+ if (output.address !== recipient.address || recipient.type === "evm" && recipient.envelope !== void 0 && typeof recipient.envelope !== "boolean" || recipient.type === "invisi" && "envelope" in recipient)
703
+ throw new Error("recipient material mismatch");
704
+ if (!note || note.chainId !== context.chainId || note.protocolAddress !== BigInt(context.protocolAddress) || note.tokenAddress !== BigInt(context.tokenAddress) || note.ownerAddress !== parsed.ownerAddress || note.amount !== output.amount || note.nonce !== recipient.nonce || note.nonce !== payment.nonce || _ethers.hexlify.call(void 0, payloadCopy(note.payload)) !== _ethers.hexlify.call(void 0, payloadCopy(payment.payload)))
705
+ throw new Error("note output opening does not match payment intent");
706
+ if (recipient.type === "evm" !== (parsed.kind === "short"))
707
+ throw new Error("recipient type mismatch");
708
+ if (await _primitives.computeNoteIdentity.call(void 0, BigInt(note.ownerAddress), nonceValue(note.nonce)) !== output.identity)
709
+ throw new Error("note output identity mismatch");
710
+ }
711
+ if (typeof output.amount !== "bigint" || output.amount <= 0n || output.amount >= 1n << 128n || await _primitives.computeNoteCommitment.call(void 0,
712
+ context.chainId,
713
+ BigInt(context.protocolAddress),
714
+ output.identity,
715
+ BigInt(context.tokenAddress),
716
+ output.amount
717
+ ) !== output.commitment)
718
+ throw new Error("note output commitment mismatch");
719
+ assertRequestMatchesOutput(payment.ipp, output);
720
+ if (pending) {
721
+ if (recipient.type !== "evm") throw new Error("only EVM outputs may have pending delivery");
722
+ const resolved = await resolveRecipient(
723
+ recipient.address,
724
+ _optionalChain([lookup, 'optionalCall', _12 => _12(_nullishCoalesce(recipient.addressLookup, () => ( "protocol-rpc")))]),
725
+ { field: "to" }
726
+ );
727
+ const keys = resolved.getReceivingKeys();
728
+ output.delivery = {
729
+ ciphertext: _ethers.hexlify.call(void 0,
730
+ await _primitives.encryptPrivateTransferNote.call(void 0, keys.viewingPublicKey, output.note, {
731
+ chainId: context.chainId,
732
+ protocolAddress: BigInt(context.protocolAddress),
733
+ outputCommitment: output.commitment
734
+ })
735
+ ),
736
+ clue: _ethers.hexlify.call(void 0, _primitives.createClue.call(void 0, keys.clueKey))
737
+ };
738
+ delete output.deliveryPending;
739
+ }
740
+ return output;
741
+ }
742
+ function resolvedOutputSnapshot(payment, output) {
743
+ const copy = structuredClone(payment);
744
+ Object.assign(copy, {
745
+ preparedOutput: structuredClone(output),
746
+ deliveryFingerprint: fingerprint(output.delivery),
747
+ deliveryPending: false
748
+ });
749
+ return copy;
750
+ }
751
+
752
+
753
+
754
+
755
+
756
+
757
+
758
+
759
+
760
+
761
+
762
+
763
+
764
+ exports.encodePaymentNote = encodePaymentNote; exports.decodePaymentNote = decodePaymentNote; exports.exportPaymentNote = exportPaymentNote; exports.InvisiError = InvisiError; exports.prepareWithErrors = prepareWithErrors; exports.resolveRecipient = resolveRecipient; exports.encodePaymentRequest = encodePaymentRequest; exports.decodePaymentRequest = decodePaymentRequest; exports.NoteOutput = NoteOutput; exports.materializeNoteOutput = materializeNoteOutput; exports.resolvedOutputSnapshot = resolvedOutputSnapshot;
765
+ //# sourceMappingURL=chunk-4SDP53YQ.cjs.map