x402z-shared-web 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -0
- package/dist/index.d.mts +391 -0
- package/dist/index.d.ts +391 -0
- package/dist/index.js +573 -0
- package/dist/index.mjs +531 -0
- package/package.json +31 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ConfidentialToken: () => ConfidentialToken,
|
|
24
|
+
SepoliaConfig: () => SepoliaConfig,
|
|
25
|
+
confidentialErrorCodes: () => confidentialErrorCodes,
|
|
26
|
+
confidentialPaymentTypes: () => confidentialPaymentTypes,
|
|
27
|
+
confidentialTokenAbi: () => confidentialTokenAbi,
|
|
28
|
+
configureRelayerSdk: () => configureRelayerSdk,
|
|
29
|
+
createEncryptedAmountInput: () => createEncryptedAmountInput,
|
|
30
|
+
createNonce: () => createNonce,
|
|
31
|
+
createRelayer: () => createRelayer,
|
|
32
|
+
decryptEuint64: () => decryptEuint64,
|
|
33
|
+
getSepoliaConfig: () => getSepoliaConfig,
|
|
34
|
+
getTransferAmounts: () => getTransferAmounts,
|
|
35
|
+
hashEncryptedAmountInput: () => hashEncryptedAmountInput,
|
|
36
|
+
initSDK: () => initSDK,
|
|
37
|
+
normalizeAmount: () => normalizeAmount,
|
|
38
|
+
publicDecrypt: () => publicDecrypt
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
|
+
|
|
42
|
+
// src/core/abi.ts
|
|
43
|
+
var confidentialTokenAbi = [
|
|
44
|
+
{
|
|
45
|
+
inputs: [
|
|
46
|
+
{ internalType: "address", name: "to", type: "address" },
|
|
47
|
+
{ internalType: "bytes32", name: "encryptedAmountInput", type: "bytes32" },
|
|
48
|
+
{ internalType: "bytes", name: "inputProof", type: "bytes" }
|
|
49
|
+
],
|
|
50
|
+
name: "confidentialTransfer",
|
|
51
|
+
outputs: [{ internalType: "euint64", name: "transferred", type: "bytes32" }],
|
|
52
|
+
stateMutability: "nonpayable",
|
|
53
|
+
type: "function"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
inputs: [
|
|
57
|
+
{
|
|
58
|
+
components: [
|
|
59
|
+
{ internalType: "address", name: "holder", type: "address" },
|
|
60
|
+
{ internalType: "address", name: "payee", type: "address" },
|
|
61
|
+
{ internalType: "uint256", name: "maxClearAmount", type: "uint256" },
|
|
62
|
+
{ internalType: "bytes32", name: "resourceHash", type: "bytes32" },
|
|
63
|
+
{ internalType: "uint48", name: "validAfter", type: "uint48" },
|
|
64
|
+
{ internalType: "uint48", name: "validBefore", type: "uint48" },
|
|
65
|
+
{ internalType: "bytes32", name: "nonce", type: "bytes32" },
|
|
66
|
+
{ internalType: "bytes32", name: "encryptedAmountHash", type: "bytes32" }
|
|
67
|
+
],
|
|
68
|
+
internalType: "struct FHEToken.ConfidentialPayment",
|
|
69
|
+
name: "p",
|
|
70
|
+
type: "tuple"
|
|
71
|
+
},
|
|
72
|
+
{ internalType: "externalEuint64", name: "encryptedAmountInput", type: "bytes32" },
|
|
73
|
+
{ internalType: "bytes", name: "inputProof", type: "bytes" },
|
|
74
|
+
{ internalType: "bytes", name: "sig", type: "bytes" }
|
|
75
|
+
],
|
|
76
|
+
name: "confidentialTransferWithAuthorization",
|
|
77
|
+
outputs: [{ internalType: "euint64", name: "transferred", type: "bytes32" }],
|
|
78
|
+
stateMutability: "nonpayable",
|
|
79
|
+
type: "function"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
inputs: [
|
|
83
|
+
{ internalType: "address", name: "to", type: "address" },
|
|
84
|
+
{ internalType: "uint256", name: "amount", type: "uint256" }
|
|
85
|
+
],
|
|
86
|
+
name: "wrap",
|
|
87
|
+
outputs: [],
|
|
88
|
+
stateMutability: "nonpayable",
|
|
89
|
+
type: "function"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
inputs: [
|
|
93
|
+
{ internalType: "address", name: "from", type: "address" },
|
|
94
|
+
{ internalType: "address", name: "to", type: "address" },
|
|
95
|
+
{ internalType: "bytes32", name: "encryptedAmountInput", type: "bytes32" },
|
|
96
|
+
{ internalType: "bytes", name: "inputProof", type: "bytes" }
|
|
97
|
+
],
|
|
98
|
+
name: "unwrap",
|
|
99
|
+
outputs: [],
|
|
100
|
+
stateMutability: "nonpayable",
|
|
101
|
+
type: "function"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
anonymous: false,
|
|
105
|
+
inputs: [
|
|
106
|
+
{ indexed: true, internalType: "address", name: "holder", type: "address" },
|
|
107
|
+
{ indexed: true, internalType: "address", name: "payee", type: "address" },
|
|
108
|
+
{ indexed: false, internalType: "uint256", name: "maxClearAmount", type: "uint256" },
|
|
109
|
+
{ indexed: true, internalType: "bytes32", name: "resourceHash", type: "bytes32" },
|
|
110
|
+
{ indexed: false, internalType: "bytes32", name: "nonce", type: "bytes32" },
|
|
111
|
+
{ indexed: false, internalType: "bytes32", name: "transferredAmount", type: "bytes32" }
|
|
112
|
+
],
|
|
113
|
+
name: "ConfidentialPaymentExecuted",
|
|
114
|
+
type: "event"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
inputs: [
|
|
118
|
+
{ internalType: "address", name: "", type: "address" },
|
|
119
|
+
{ internalType: "bytes32", name: "", type: "bytes32" }
|
|
120
|
+
],
|
|
121
|
+
name: "usedNonces",
|
|
122
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
123
|
+
stateMutability: "view",
|
|
124
|
+
type: "function"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
inputs: [{ internalType: "address", name: "account", type: "address" }],
|
|
128
|
+
name: "observer",
|
|
129
|
+
outputs: [{ internalType: "address", name: "", type: "address" }],
|
|
130
|
+
stateMutability: "view",
|
|
131
|
+
type: "function"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
inputs: [
|
|
135
|
+
{ internalType: "address", name: "account", type: "address" },
|
|
136
|
+
{ internalType: "address", name: "newObserver", type: "address" }
|
|
137
|
+
],
|
|
138
|
+
name: "setObserver",
|
|
139
|
+
outputs: [],
|
|
140
|
+
stateMutability: "nonpayable",
|
|
141
|
+
type: "function"
|
|
142
|
+
}
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
// src/core/constants.ts
|
|
146
|
+
var confidentialPaymentTypes = {
|
|
147
|
+
ConfidentialPayment: [
|
|
148
|
+
{ name: "holder", type: "address" },
|
|
149
|
+
{ name: "payee", type: "address" },
|
|
150
|
+
{ name: "maxClearAmount", type: "uint256" },
|
|
151
|
+
{ name: "resourceHash", type: "bytes32" },
|
|
152
|
+
{ name: "validAfter", type: "uint48" },
|
|
153
|
+
{ name: "validBefore", type: "uint48" },
|
|
154
|
+
{ name: "nonce", type: "bytes32" },
|
|
155
|
+
{ name: "encryptedAmountHash", type: "bytes32" }
|
|
156
|
+
]
|
|
157
|
+
};
|
|
158
|
+
var confidentialErrorCodes = {
|
|
159
|
+
observerNotAuthorized: "observer_not_authorized"
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// src/core/utils.ts
|
|
163
|
+
var import_viem = require("viem");
|
|
164
|
+
function createNonce() {
|
|
165
|
+
const cryptoObj = typeof globalThis.crypto !== "undefined" ? globalThis.crypto : globalThis.crypto;
|
|
166
|
+
if (!cryptoObj) {
|
|
167
|
+
throw new Error("Crypto API not available");
|
|
168
|
+
}
|
|
169
|
+
return (0, import_viem.toHex)(cryptoObj.getRandomValues(new Uint8Array(32)));
|
|
170
|
+
}
|
|
171
|
+
function hashEncryptedAmountInput(encryptedAmountInput) {
|
|
172
|
+
return (0, import_viem.keccak256)(
|
|
173
|
+
(0, import_viem.encodeAbiParameters)([{ type: "bytes32" }], [encryptedAmountInput])
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
function normalizeAmount(amount) {
|
|
177
|
+
if (typeof amount === "string") {
|
|
178
|
+
return amount;
|
|
179
|
+
}
|
|
180
|
+
if (typeof amount === "number") {
|
|
181
|
+
if (!Number.isFinite(amount)) {
|
|
182
|
+
throw new Error("Invalid amount");
|
|
183
|
+
}
|
|
184
|
+
return Math.trunc(amount).toString();
|
|
185
|
+
}
|
|
186
|
+
return amount.toString();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/relayer/index.ts
|
|
190
|
+
var import_viem2 = require("viem");
|
|
191
|
+
var relayerSdk = null;
|
|
192
|
+
var SepoliaConfig;
|
|
193
|
+
async function getRelayerSdk() {
|
|
194
|
+
if (relayerSdk) {
|
|
195
|
+
return relayerSdk;
|
|
196
|
+
}
|
|
197
|
+
throw new Error(
|
|
198
|
+
"Relayer SDK not configured. Call configureRelayerSdk() with the CDN module before initSDK/createRelayer."
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
function configureRelayerSdk(sdk) {
|
|
202
|
+
relayerSdk = sdk;
|
|
203
|
+
SepoliaConfig = sdk.SepoliaConfig;
|
|
204
|
+
}
|
|
205
|
+
function getSepoliaConfig() {
|
|
206
|
+
if (!SepoliaConfig) {
|
|
207
|
+
throw new Error("SepoliaConfig is not available; call configureRelayerSdk or initSDK first");
|
|
208
|
+
}
|
|
209
|
+
return SepoliaConfig;
|
|
210
|
+
}
|
|
211
|
+
async function createRelayer(config) {
|
|
212
|
+
const sdk = await getRelayerSdk();
|
|
213
|
+
const instance = await sdk.createInstance(config);
|
|
214
|
+
if (typeof config.network === "string") {
|
|
215
|
+
instance.network = config.network;
|
|
216
|
+
}
|
|
217
|
+
return instance;
|
|
218
|
+
}
|
|
219
|
+
async function initSDK(params) {
|
|
220
|
+
const sdk = await getRelayerSdk();
|
|
221
|
+
return sdk.initSDK(params);
|
|
222
|
+
}
|
|
223
|
+
async function createEncryptedAmountInput(relayer, contractAddress, senderAddress, amount) {
|
|
224
|
+
const normalizedContract = (0, import_viem2.getAddress)(contractAddress);
|
|
225
|
+
const normalizedSender = (0, import_viem2.getAddress)(senderAddress);
|
|
226
|
+
const encrypted = await relayer.createEncryptedInput(normalizedContract, normalizedSender).add64(amount).encrypt();
|
|
227
|
+
const handle = typeof encrypted.handles[0] === "string" ? encrypted.handles[0] : (0, import_viem2.toHex)(encrypted.handles[0]);
|
|
228
|
+
const inputProof = typeof encrypted.inputProof === "string" ? encrypted.inputProof : (0, import_viem2.toHex)(encrypted.inputProof);
|
|
229
|
+
return {
|
|
230
|
+
handle,
|
|
231
|
+
inputProof
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
async function decryptEuint64(relayer, handle, contractAddress, signer, options) {
|
|
235
|
+
const keypair = relayer.generateKeypair();
|
|
236
|
+
const startTimestamp = options?.startTimestamp ?? Math.floor(Date.now() / 1e3).toString();
|
|
237
|
+
const durationDays = options?.durationDays ?? "10";
|
|
238
|
+
const contractAddresses = [contractAddress];
|
|
239
|
+
const eip712 = relayer.createEIP712(keypair.publicKey, contractAddresses, startTimestamp, durationDays);
|
|
240
|
+
const types = { UserDecryptRequestVerification: eip712.types.UserDecryptRequestVerification };
|
|
241
|
+
const sign = signer.signTypedData;
|
|
242
|
+
const signature = sign.length >= 3 ? await sign(eip712.domain, types, eip712.message) : await sign({
|
|
243
|
+
domain: eip712.domain,
|
|
244
|
+
types,
|
|
245
|
+
primaryType: "UserDecryptRequestVerification",
|
|
246
|
+
message: eip712.message
|
|
247
|
+
});
|
|
248
|
+
const result = await relayer.userDecrypt(
|
|
249
|
+
[{ handle, contractAddress }],
|
|
250
|
+
keypair.privateKey,
|
|
251
|
+
keypair.publicKey,
|
|
252
|
+
signature.replace("0x", ""),
|
|
253
|
+
contractAddresses,
|
|
254
|
+
signer.address,
|
|
255
|
+
startTimestamp,
|
|
256
|
+
durationDays
|
|
257
|
+
);
|
|
258
|
+
return result[handle];
|
|
259
|
+
}
|
|
260
|
+
async function publicDecrypt(relayer, handles) {
|
|
261
|
+
const result = await relayer.publicDecrypt(handles);
|
|
262
|
+
return {
|
|
263
|
+
clearValues: result.clearValues,
|
|
264
|
+
decryptionProof: result.decryptionProof
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/token/transfer.ts
|
|
269
|
+
var import_viem3 = require("viem");
|
|
270
|
+
async function getTransferAmounts(options) {
|
|
271
|
+
if (!(0, import_viem3.isAddress)(options.tokenAddress)) {
|
|
272
|
+
throw new Error(`Invalid token address: ${options.tokenAddress}`);
|
|
273
|
+
}
|
|
274
|
+
if (!(0, import_viem3.isHex)(options.txHash, { strict: true })) {
|
|
275
|
+
throw new Error(`Invalid transaction hash: ${options.txHash}`);
|
|
276
|
+
}
|
|
277
|
+
if (options.from && !(0, import_viem3.isAddress)(options.from)) {
|
|
278
|
+
throw new Error(`Invalid from address: ${options.from}`);
|
|
279
|
+
}
|
|
280
|
+
if (options.to && !(0, import_viem3.isAddress)(options.to)) {
|
|
281
|
+
throw new Error(`Invalid to address: ${options.to}`);
|
|
282
|
+
}
|
|
283
|
+
const publicClient = (0, import_viem3.createPublicClient)({ transport: (0, import_viem3.http)(options.rpcUrl) });
|
|
284
|
+
const receipt = await publicClient.getTransactionReceipt({
|
|
285
|
+
hash: options.txHash
|
|
286
|
+
});
|
|
287
|
+
const tokenAddress = (0, import_viem3.getAddress)(options.tokenAddress);
|
|
288
|
+
const fromFilter = options.from ? (0, import_viem3.getAddress)(options.from) : void 0;
|
|
289
|
+
const toFilter = options.to ? (0, import_viem3.getAddress)(options.to) : void 0;
|
|
290
|
+
const logs = receipt.logs.filter((log) => (0, import_viem3.getAddress)(log.address) === tokenAddress);
|
|
291
|
+
const transfers = [];
|
|
292
|
+
for (const log of logs) {
|
|
293
|
+
try {
|
|
294
|
+
const decoded = (0, import_viem3.decodeEventLog)({
|
|
295
|
+
abi: confidentialTokenAbi,
|
|
296
|
+
eventName: "ConfidentialPaymentExecuted",
|
|
297
|
+
data: log.data,
|
|
298
|
+
topics: log.topics
|
|
299
|
+
});
|
|
300
|
+
const args = decoded.args;
|
|
301
|
+
const entry = {
|
|
302
|
+
holder: (0, import_viem3.getAddress)(args.holder),
|
|
303
|
+
payee: (0, import_viem3.getAddress)(args.payee),
|
|
304
|
+
maxClearAmount: BigInt(args.maxClearAmount),
|
|
305
|
+
resourceHash: args.resourceHash,
|
|
306
|
+
nonce: args.nonce,
|
|
307
|
+
handle: args.transferredAmount
|
|
308
|
+
};
|
|
309
|
+
if (fromFilter && entry.holder !== fromFilter) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
if (toFilter && entry.payee !== toFilter) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const shouldDecrypt = options.decrypt ?? true;
|
|
316
|
+
if (shouldDecrypt) {
|
|
317
|
+
if (!options.signer) {
|
|
318
|
+
throw new Error("Missing signer for decryption");
|
|
319
|
+
}
|
|
320
|
+
const signerAddress = (0, import_viem3.getAddress)(options.signer.address);
|
|
321
|
+
const holderAddress = (0, import_viem3.getAddress)(entry.holder);
|
|
322
|
+
const payeeAddress = (0, import_viem3.getAddress)(entry.payee);
|
|
323
|
+
if (!(0, import_viem3.isAddressEqual)(signerAddress, holderAddress) && !(0, import_viem3.isAddressEqual)(signerAddress, payeeAddress)) {
|
|
324
|
+
const [holderObserver, payeeObserver] = await Promise.all([
|
|
325
|
+
publicClient.readContract({
|
|
326
|
+
address: tokenAddress,
|
|
327
|
+
abi: confidentialTokenAbi,
|
|
328
|
+
functionName: "observer",
|
|
329
|
+
args: [holderAddress]
|
|
330
|
+
}),
|
|
331
|
+
publicClient.readContract({
|
|
332
|
+
address: tokenAddress,
|
|
333
|
+
abi: confidentialTokenAbi,
|
|
334
|
+
functionName: "observer",
|
|
335
|
+
args: [payeeAddress]
|
|
336
|
+
})
|
|
337
|
+
]);
|
|
338
|
+
const allowed = holderObserver && (0, import_viem3.isAddressEqual)(holderObserver, signerAddress) || payeeObserver && (0, import_viem3.isAddressEqual)(payeeObserver, signerAddress);
|
|
339
|
+
if (!allowed) {
|
|
340
|
+
throw new Error(confidentialErrorCodes.observerNotAuthorized);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
entry.amount = await decryptEuint64(
|
|
344
|
+
options.relayer,
|
|
345
|
+
entry.handle,
|
|
346
|
+
tokenAddress,
|
|
347
|
+
options.signer
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
transfers.push(entry);
|
|
351
|
+
} catch (error) {
|
|
352
|
+
if (error instanceof Error && error.message.includes("ConfidentialPaymentExecuted")) {
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return transfers;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/token/token.ts
|
|
361
|
+
var import_viem6 = require("viem");
|
|
362
|
+
|
|
363
|
+
// src/token/balance.ts
|
|
364
|
+
var import_viem4 = require("viem");
|
|
365
|
+
var ZERO_HANDLE = "0x" + "00".repeat(32);
|
|
366
|
+
async function readBalance(options) {
|
|
367
|
+
if (!(0, import_viem4.isAddress)(options.tokenAddress)) {
|
|
368
|
+
throw new Error(`Invalid token address: ${options.tokenAddress}`);
|
|
369
|
+
}
|
|
370
|
+
const account = options.account ?? options.signer?.address;
|
|
371
|
+
if (!account || !(0, import_viem4.isAddress)(account)) {
|
|
372
|
+
throw new Error(`Invalid account address: ${account ?? "undefined"}`);
|
|
373
|
+
}
|
|
374
|
+
const publicClient = (0, import_viem4.createPublicClient)({ transport: (0, import_viem4.http)(options.rpcUrl) });
|
|
375
|
+
const confidentialBalanceAbi = [
|
|
376
|
+
{
|
|
377
|
+
inputs: [{ internalType: "address", name: "account", type: "address" }],
|
|
378
|
+
name: "confidentialBalanceOf",
|
|
379
|
+
outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }],
|
|
380
|
+
stateMutability: "view",
|
|
381
|
+
type: "function"
|
|
382
|
+
}
|
|
383
|
+
];
|
|
384
|
+
const handle = await publicClient.readContract({
|
|
385
|
+
address: options.tokenAddress,
|
|
386
|
+
abi: confidentialBalanceAbi,
|
|
387
|
+
functionName: "confidentialBalanceOf",
|
|
388
|
+
args: [account]
|
|
389
|
+
});
|
|
390
|
+
const shouldDecrypt = options.decrypt ?? true;
|
|
391
|
+
if (!shouldDecrypt) {
|
|
392
|
+
return { handle };
|
|
393
|
+
}
|
|
394
|
+
if (!options.signer) {
|
|
395
|
+
throw new Error("Missing signer for decryption");
|
|
396
|
+
}
|
|
397
|
+
const signerAddress = (0, import_viem4.getAddress)(options.signer.address);
|
|
398
|
+
if (!(0, import_viem4.isAddressEqual)(signerAddress, (0, import_viem4.getAddress)(account))) {
|
|
399
|
+
const observer = await publicClient.readContract({
|
|
400
|
+
address: options.tokenAddress,
|
|
401
|
+
abi: confidentialTokenAbi,
|
|
402
|
+
functionName: "observer",
|
|
403
|
+
args: [account]
|
|
404
|
+
});
|
|
405
|
+
if (!observer || !(0, import_viem4.isAddressEqual)(observer, signerAddress)) {
|
|
406
|
+
throw new Error(confidentialErrorCodes.observerNotAuthorized);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (handle === ZERO_HANDLE) {
|
|
410
|
+
return { handle, balance: 0n };
|
|
411
|
+
}
|
|
412
|
+
const balance = await decryptEuint64(options.relayer, handle, options.tokenAddress, options.signer);
|
|
413
|
+
return { handle, balance };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/token/observer.ts
|
|
417
|
+
var import_viem5 = require("viem");
|
|
418
|
+
async function setObserver(options) {
|
|
419
|
+
if (!(0, import_viem5.isAddress)(options.tokenAddress)) {
|
|
420
|
+
throw new Error(`Invalid token address: ${options.tokenAddress}`);
|
|
421
|
+
}
|
|
422
|
+
if (!(0, import_viem5.isAddress)(options.account)) {
|
|
423
|
+
throw new Error(`Invalid account address: ${options.account}`);
|
|
424
|
+
}
|
|
425
|
+
if (!(0, import_viem5.isAddress)(options.observer)) {
|
|
426
|
+
throw new Error(`Invalid observer address: ${options.observer}`);
|
|
427
|
+
}
|
|
428
|
+
return options.walletClient.writeContract({
|
|
429
|
+
address: (0, import_viem5.getAddress)(options.tokenAddress),
|
|
430
|
+
abi: confidentialTokenAbi,
|
|
431
|
+
functionName: "setObserver",
|
|
432
|
+
args: [(0, import_viem5.getAddress)(options.account), (0, import_viem5.getAddress)(options.observer)],
|
|
433
|
+
chain: options.walletClient.chain ?? null,
|
|
434
|
+
account: options.signer ?? options.walletClient.account ?? null
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// src/token/token.ts
|
|
439
|
+
function assertAddress(value, label) {
|
|
440
|
+
if (!(0, import_viem6.isAddress)(value)) {
|
|
441
|
+
throw new Error(`Invalid ${label}: ${value}`);
|
|
442
|
+
}
|
|
443
|
+
return (0, import_viem6.getAddress)(value);
|
|
444
|
+
}
|
|
445
|
+
function resolveSignerAddress(signer, walletClient) {
|
|
446
|
+
if (signer?.address) {
|
|
447
|
+
return assertAddress(signer.address, "signer address");
|
|
448
|
+
}
|
|
449
|
+
const account = walletClient.account;
|
|
450
|
+
if (typeof account === "string") {
|
|
451
|
+
return assertAddress(account, "wallet address");
|
|
452
|
+
}
|
|
453
|
+
if (account && typeof account === "object" && "address" in account && account.address) {
|
|
454
|
+
return assertAddress(account.address, "wallet address");
|
|
455
|
+
}
|
|
456
|
+
throw new Error("Missing signer address");
|
|
457
|
+
}
|
|
458
|
+
function resolveWriteAccount(signer, walletClient) {
|
|
459
|
+
if (signer?.address) {
|
|
460
|
+
return assertAddress(signer.address, "signer address");
|
|
461
|
+
}
|
|
462
|
+
const account = walletClient.account;
|
|
463
|
+
if (typeof account === "string") {
|
|
464
|
+
return assertAddress(account, "wallet address");
|
|
465
|
+
}
|
|
466
|
+
return account ?? null;
|
|
467
|
+
}
|
|
468
|
+
var ConfidentialToken = class {
|
|
469
|
+
constructor(config) {
|
|
470
|
+
this.rpcUrl = config.rpcUrl;
|
|
471
|
+
this.tokenAddress = config.tokenAddress;
|
|
472
|
+
this.relayer = config.relayer;
|
|
473
|
+
this.walletClient = config.walletClient;
|
|
474
|
+
this.signer = config.signer;
|
|
475
|
+
}
|
|
476
|
+
async balanceOf(account) {
|
|
477
|
+
const result = await readBalance({
|
|
478
|
+
rpcUrl: this.rpcUrl,
|
|
479
|
+
tokenAddress: this.tokenAddress,
|
|
480
|
+
account,
|
|
481
|
+
relayer: this.relayer,
|
|
482
|
+
signer: this.signer,
|
|
483
|
+
decrypt: true
|
|
484
|
+
});
|
|
485
|
+
return result.balance ?? 0n;
|
|
486
|
+
}
|
|
487
|
+
async setObserver(account, observer) {
|
|
488
|
+
return setObserver({
|
|
489
|
+
tokenAddress: this.tokenAddress,
|
|
490
|
+
account,
|
|
491
|
+
observer,
|
|
492
|
+
signer: this.signer?.address ? assertAddress(this.signer.address, "signer address") : void 0,
|
|
493
|
+
walletClient: this.walletClient
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
async transfer(to, amount) {
|
|
497
|
+
const tokenAddress = assertAddress(this.tokenAddress, "token address");
|
|
498
|
+
const toAddress = assertAddress(to, "recipient address");
|
|
499
|
+
const fromAddress = resolveSignerAddress(this.signer, this.walletClient);
|
|
500
|
+
if (!Number.isSafeInteger(amount)) {
|
|
501
|
+
throw new Error("Transfer amount must be a safe integer");
|
|
502
|
+
}
|
|
503
|
+
const { handle, inputProof } = await createEncryptedAmountInput(
|
|
504
|
+
this.relayer,
|
|
505
|
+
tokenAddress,
|
|
506
|
+
fromAddress,
|
|
507
|
+
amount
|
|
508
|
+
);
|
|
509
|
+
return this.walletClient.writeContract({
|
|
510
|
+
address: tokenAddress,
|
|
511
|
+
abi: confidentialTokenAbi,
|
|
512
|
+
functionName: "confidentialTransfer",
|
|
513
|
+
args: [toAddress, handle, inputProof],
|
|
514
|
+
chain: this.walletClient.chain ?? null,
|
|
515
|
+
account: resolveWriteAccount(this.signer, this.walletClient)
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
async wrap(to, amount) {
|
|
519
|
+
const tokenAddress = assertAddress(this.tokenAddress, "token address");
|
|
520
|
+
const toAddress = assertAddress(to, "recipient address");
|
|
521
|
+
const normalizedAmount = BigInt(normalizeAmount(amount));
|
|
522
|
+
return this.walletClient.writeContract({
|
|
523
|
+
address: tokenAddress,
|
|
524
|
+
abi: confidentialTokenAbi,
|
|
525
|
+
functionName: "wrap",
|
|
526
|
+
args: [toAddress, normalizedAmount],
|
|
527
|
+
chain: this.walletClient.chain ?? null,
|
|
528
|
+
account: resolveWriteAccount(this.signer, this.walletClient)
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
async unwrap(from, to, amount) {
|
|
532
|
+
const tokenAddress = assertAddress(this.tokenAddress, "token address");
|
|
533
|
+
const fromAddress = assertAddress(from, "from address");
|
|
534
|
+
const toAddress = assertAddress(to, "to address");
|
|
535
|
+
const signerAddress = resolveSignerAddress(this.signer, this.walletClient);
|
|
536
|
+
if (!Number.isSafeInteger(amount)) {
|
|
537
|
+
throw new Error("Unwrap amount must be a safe integer");
|
|
538
|
+
}
|
|
539
|
+
const { handle, inputProof } = await createEncryptedAmountInput(
|
|
540
|
+
this.relayer,
|
|
541
|
+
tokenAddress,
|
|
542
|
+
signerAddress,
|
|
543
|
+
amount
|
|
544
|
+
);
|
|
545
|
+
return this.walletClient.writeContract({
|
|
546
|
+
address: tokenAddress,
|
|
547
|
+
abi: confidentialTokenAbi,
|
|
548
|
+
functionName: "unwrap",
|
|
549
|
+
args: [fromAddress, toAddress, handle, inputProof],
|
|
550
|
+
chain: this.walletClient.chain ?? null,
|
|
551
|
+
account: resolveWriteAccount(this.signer, this.walletClient)
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
556
|
+
0 && (module.exports = {
|
|
557
|
+
ConfidentialToken,
|
|
558
|
+
SepoliaConfig,
|
|
559
|
+
confidentialErrorCodes,
|
|
560
|
+
confidentialPaymentTypes,
|
|
561
|
+
confidentialTokenAbi,
|
|
562
|
+
configureRelayerSdk,
|
|
563
|
+
createEncryptedAmountInput,
|
|
564
|
+
createNonce,
|
|
565
|
+
createRelayer,
|
|
566
|
+
decryptEuint64,
|
|
567
|
+
getSepoliaConfig,
|
|
568
|
+
getTransferAmounts,
|
|
569
|
+
hashEncryptedAmountInput,
|
|
570
|
+
initSDK,
|
|
571
|
+
normalizeAmount,
|
|
572
|
+
publicDecrypt
|
|
573
|
+
});
|