@glowlabs-org/utils 0.2.113 → 0.2.115
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/cjs/browser.js +1 -1
- package/dist/cjs/{farms-router-djet_3Cn.js → farms-router-CuZE5YJ_.js} +414 -252
- package/dist/cjs/farms-router-CuZE5YJ_.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/lib/hooks/use-offchain-fractions.d.ts +2 -2
- package/dist/esm/browser.js +2 -2
- package/dist/esm/{farms-router-CDZkFsAs.js → farms-router-BUi6rxeX.js} +414 -252
- package/dist/esm/farms-router-BUi6rxeX.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/lib/hooks/use-offchain-fractions.d.ts +2 -2
- package/package.json +1 -1
- package/src/constants/addresses.ts +1 -1
- package/src/lib/hooks/use-offchain-fractions.ts +390 -319
- package/dist/cjs/farms-router-djet_3Cn.js.map +0 -1
- package/dist/esm/farms-router-CDZkFsAs.js.map +0 -1
|
@@ -225,7 +225,7 @@ const sepoliaAddresses = {
|
|
|
225
225
|
USDG_UNISWAP: "0x2a085A3aEA8982396533327c854753Ce521B666d",
|
|
226
226
|
GLW_UNISWAP: "0x8e27016D0B866a56CE74A1a280c749dD679bb0Fa",
|
|
227
227
|
FORWARDER: "0xDaC24F18171224eeaf6a9B38f5C5081aDbDff969",
|
|
228
|
-
OFFCHAIN_FRACTIONS: "
|
|
228
|
+
OFFCHAIN_FRACTIONS: "0x7D97528eeF8B8D17AA1Ba3307Ed39b07b3A1b69B",
|
|
229
229
|
COUNTERFACTUAL_HOLDER_FACTORY: "0x2c3AB887746F6f4a8a4b9Db6aC800eb71945509A",
|
|
230
230
|
FOUNDATION_WALLET: "0x5e230FED487c86B90f6508104149F087d9B1B0A7",
|
|
231
231
|
UNISWAP_V2_ROUTER: "0xeE567Fe1712Faf6149d80dA1E6934E354124CfE3",
|
|
@@ -290,7 +290,7 @@ exports.ForwarderError = void 0;
|
|
|
290
290
|
ForwarderError["MISSING_REQUIRED_PARAMS"] = "Missing required parameters";
|
|
291
291
|
})(exports.ForwarderError || (exports.ForwarderError = {}));
|
|
292
292
|
// Utility to extract the most useful revert reason from an ethers error object
|
|
293
|
-
function parseEthersError
|
|
293
|
+
function parseEthersError(error) {
|
|
294
294
|
if (!error)
|
|
295
295
|
return "Unknown error";
|
|
296
296
|
const possibleError = error;
|
|
@@ -317,7 +317,7 @@ function parseEthersError$1(error) {
|
|
|
317
317
|
return exports.ForwarderError.UNKNOWN_ERROR;
|
|
318
318
|
}
|
|
319
319
|
// Type-guard style helper to ensure a signer exists throughout the rest of the function.
|
|
320
|
-
function assertSigner
|
|
320
|
+
function assertSigner(maybeSigner) {
|
|
321
321
|
if (!maybeSigner) {
|
|
322
322
|
throw new Error(exports.ForwarderError.SIGNER_NOT_AVAILABLE);
|
|
323
323
|
}
|
|
@@ -332,7 +332,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
332
332
|
};
|
|
333
333
|
// Returns a contract instance for Forwarder
|
|
334
334
|
function getForwarderContract() {
|
|
335
|
-
assertSigner
|
|
335
|
+
assertSigner(signer);
|
|
336
336
|
return new ethers.Contract(ADDRESSES.FORWARDER, FORWARDER_ABI, signer);
|
|
337
337
|
}
|
|
338
338
|
/**
|
|
@@ -394,7 +394,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
394
394
|
* Get the appropriate token contract based on currency
|
|
395
395
|
*/
|
|
396
396
|
function getTokenContract(currency = "USDC") {
|
|
397
|
-
assertSigner
|
|
397
|
+
assertSigner(signer);
|
|
398
398
|
let tokenAddress;
|
|
399
399
|
switch (currency) {
|
|
400
400
|
case "USDC":
|
|
@@ -417,7 +417,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
417
417
|
* @param currency The currency to check allowance for
|
|
418
418
|
*/
|
|
419
419
|
async function checkTokenAllowance(owner, currency = "USDC") {
|
|
420
|
-
assertSigner
|
|
420
|
+
assertSigner(signer);
|
|
421
421
|
try {
|
|
422
422
|
const tokenContract = getTokenContract(currency);
|
|
423
423
|
if (!tokenContract)
|
|
@@ -426,7 +426,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
426
426
|
return allowance;
|
|
427
427
|
}
|
|
428
428
|
catch (error) {
|
|
429
|
-
throw new Error(parseEthersError
|
|
429
|
+
throw new Error(parseEthersError(error));
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
/**
|
|
@@ -435,7 +435,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
435
435
|
* @param currency The currency to check balance for
|
|
436
436
|
*/
|
|
437
437
|
async function checkTokenBalance(owner, currency = "USDC") {
|
|
438
|
-
assertSigner
|
|
438
|
+
assertSigner(signer);
|
|
439
439
|
try {
|
|
440
440
|
const tokenContract = getTokenContract(currency);
|
|
441
441
|
if (!tokenContract)
|
|
@@ -444,7 +444,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
444
444
|
return balance;
|
|
445
445
|
}
|
|
446
446
|
catch (error) {
|
|
447
|
-
throw new Error(parseEthersError
|
|
447
|
+
throw new Error(parseEthersError(error));
|
|
448
448
|
}
|
|
449
449
|
}
|
|
450
450
|
/**
|
|
@@ -453,7 +453,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
453
453
|
* @param currency The currency to approve
|
|
454
454
|
*/
|
|
455
455
|
async function approveToken(amount, currency = "USDC") {
|
|
456
|
-
assertSigner
|
|
456
|
+
assertSigner(signer);
|
|
457
457
|
try {
|
|
458
458
|
const tokenContract = getTokenContract(currency);
|
|
459
459
|
if (!tokenContract)
|
|
@@ -465,7 +465,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
465
465
|
return true;
|
|
466
466
|
}
|
|
467
467
|
catch (error) {
|
|
468
|
-
throw new Error(parseEthersError
|
|
468
|
+
throw new Error(parseEthersError(error));
|
|
469
469
|
}
|
|
470
470
|
finally {
|
|
471
471
|
setIsProcessing(false);
|
|
@@ -476,7 +476,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
476
476
|
* @param params Forward parameters including type, amount, and required fields
|
|
477
477
|
*/
|
|
478
478
|
async function forwardTokens(params) {
|
|
479
|
-
assertSigner
|
|
479
|
+
assertSigner(signer);
|
|
480
480
|
try {
|
|
481
481
|
const forwarderContract = getForwarderContract();
|
|
482
482
|
if (!forwarderContract)
|
|
@@ -508,7 +508,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
508
508
|
await approveTx.wait();
|
|
509
509
|
}
|
|
510
510
|
catch (approveError) {
|
|
511
|
-
throw new Error(parseEthersError
|
|
511
|
+
throw new Error(parseEthersError(approveError) || "Token approval failed");
|
|
512
512
|
}
|
|
513
513
|
}
|
|
514
514
|
// Get the token address based on currency
|
|
@@ -546,7 +546,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
546
546
|
}
|
|
547
547
|
}
|
|
548
548
|
catch (staticError) {
|
|
549
|
-
throw new Error(parseEthersError
|
|
549
|
+
throw new Error(parseEthersError(staticError));
|
|
550
550
|
}
|
|
551
551
|
// Execute the forward transaction
|
|
552
552
|
let tx;
|
|
@@ -562,7 +562,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
562
562
|
return tx.hash;
|
|
563
563
|
}
|
|
564
564
|
catch (txError) {
|
|
565
|
-
throw new Error(parseEthersError
|
|
565
|
+
throw new Error(parseEthersError(txError));
|
|
566
566
|
}
|
|
567
567
|
finally {
|
|
568
568
|
setIsProcessing(false);
|
|
@@ -572,7 +572,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
572
572
|
* Forward tokens for protocol fee payment and GCTL minting with staking
|
|
573
573
|
*/
|
|
574
574
|
async function payProtocolFeeAndMintGCTLAndStake(amount, userAddress, applicationId, regionId, currency = "USDC") {
|
|
575
|
-
assertSigner
|
|
575
|
+
assertSigner(signer);
|
|
576
576
|
// GCTL minting only supports USDC and USDG
|
|
577
577
|
if (currency === "GLW") {
|
|
578
578
|
throw new Error("GCTL minting is not supported with GLW payment. Use USDC or USDG.");
|
|
@@ -590,7 +590,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
590
590
|
* Forward tokens for protocol fee payment and GCTL minting with staking
|
|
591
591
|
*/
|
|
592
592
|
async function sponsorProtocolFeeAndMintGCTLAndStake(amount, userAddress, applicationId, currency = "USDC") {
|
|
593
|
-
assertSigner
|
|
593
|
+
assertSigner(signer);
|
|
594
594
|
if (currency === "GLW") {
|
|
595
595
|
throw new Error("GCTL minting is not supported with GLW payment. Use USDC or USDG.");
|
|
596
596
|
}
|
|
@@ -606,7 +606,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
606
606
|
* Forward tokens for protocol fee payment only
|
|
607
607
|
*/
|
|
608
608
|
async function payProtocolFee(amount, userAddress, applicationId, currency = "USDC") {
|
|
609
|
-
assertSigner
|
|
609
|
+
assertSigner(signer);
|
|
610
610
|
return forwardTokens({
|
|
611
611
|
amount,
|
|
612
612
|
userAddress,
|
|
@@ -619,7 +619,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
619
619
|
* Forward tokens for protocol fee payment only
|
|
620
620
|
*/
|
|
621
621
|
async function sponsorProtocolFee(amount, userAddress, applicationId, currency = "USDC") {
|
|
622
|
-
assertSigner
|
|
622
|
+
assertSigner(signer);
|
|
623
623
|
return forwardTokens({
|
|
624
624
|
amount,
|
|
625
625
|
userAddress,
|
|
@@ -632,7 +632,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
632
632
|
* Forward USDC to mint GCTL and stake to a region
|
|
633
633
|
*/
|
|
634
634
|
async function mintGCTLAndStake(amount, userAddress, regionId, currency = "USDC") {
|
|
635
|
-
assertSigner
|
|
635
|
+
assertSigner(signer);
|
|
636
636
|
// GCTL minting only supports USDC and USDG
|
|
637
637
|
if (currency === "GLW") {
|
|
638
638
|
throw new Error("GCTL minting is not supported with GLW payment. Use USDC or USDG.");
|
|
@@ -649,7 +649,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
649
649
|
* Forward USDC to mint GCTL (existing functionality, keeping for compatibility)
|
|
650
650
|
*/
|
|
651
651
|
async function mintGCTL(amount, userAddress, currency = "USDC") {
|
|
652
|
-
assertSigner
|
|
652
|
+
assertSigner(signer);
|
|
653
653
|
// GCTL minting only supports USDC and USDG
|
|
654
654
|
if (currency === "GLW") {
|
|
655
655
|
throw new Error("GCTL minting is not supported with GLW payment. Use USDC or USDG.");
|
|
@@ -665,7 +665,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
665
665
|
* Forward tokens to pay audit fees (USDC only, calls forward())
|
|
666
666
|
*/
|
|
667
667
|
async function payAuditFees(amount, userAddress, applicationId) {
|
|
668
|
-
assertSigner
|
|
668
|
+
assertSigner(signer);
|
|
669
669
|
return forwardTokens({
|
|
670
670
|
amount,
|
|
671
671
|
userAddress,
|
|
@@ -678,7 +678,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
678
678
|
* Forward tokens to buy a solar farm
|
|
679
679
|
*/
|
|
680
680
|
async function buySolarFarm(amount, userAddress, farmId, currency = "USDC") {
|
|
681
|
-
assertSigner
|
|
681
|
+
assertSigner(signer);
|
|
682
682
|
return forwardTokens({
|
|
683
683
|
amount,
|
|
684
684
|
userAddress,
|
|
@@ -691,7 +691,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
691
691
|
* Forward tokens to commit to a Kickstarter (USDC or USDG only)
|
|
692
692
|
*/
|
|
693
693
|
async function commitKickstarter(amount, userAddress, kickstarterId, currency = "USDC") {
|
|
694
|
-
assertSigner
|
|
694
|
+
assertSigner(signer);
|
|
695
695
|
if (currency === "GLW") {
|
|
696
696
|
throw new Error("CommitKickstarter supports only USDC or USDG");
|
|
697
697
|
}
|
|
@@ -709,7 +709,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
709
709
|
* @param ethPriceInUSD Current ETH price in USD (for cost estimation)
|
|
710
710
|
*/
|
|
711
711
|
async function estimateGasForForward(params, ethPriceInUSD) {
|
|
712
|
-
assertSigner
|
|
712
|
+
assertSigner(signer);
|
|
713
713
|
try {
|
|
714
714
|
const forwarderContract = getForwarderContract();
|
|
715
715
|
if (!forwarderContract)
|
|
@@ -763,7 +763,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
763
763
|
}
|
|
764
764
|
}
|
|
765
765
|
catch (error) {
|
|
766
|
-
throw new Error(parseEthersError
|
|
766
|
+
throw new Error(parseEthersError(error));
|
|
767
767
|
}
|
|
768
768
|
}
|
|
769
769
|
/**
|
|
@@ -772,7 +772,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
772
772
|
* @param recipient Address to mint USDC to
|
|
773
773
|
*/
|
|
774
774
|
async function mintTestUSDC(amount, recipient) {
|
|
775
|
-
assertSigner
|
|
775
|
+
assertSigner(signer);
|
|
776
776
|
if (CHAIN_ID !== 11155111) {
|
|
777
777
|
throw new Error("Minting test USDC is only supported on Sepolia");
|
|
778
778
|
}
|
|
@@ -788,7 +788,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
788
788
|
}
|
|
789
789
|
catch (error) {
|
|
790
790
|
// If mint function doesn't exist or fails, provide helpful error
|
|
791
|
-
const errorMessage = parseEthersError
|
|
791
|
+
const errorMessage = parseEthersError(error);
|
|
792
792
|
if (errorMessage.includes("mint")) {
|
|
793
793
|
throw new Error("This USDC contract doesn't support minting");
|
|
794
794
|
}
|
|
@@ -1300,40 +1300,37 @@ exports.OffchainFractionsError = void 0;
|
|
|
1300
1300
|
OffchainFractionsError["INSUFFICIENT_BALANCE"] = "Insufficient balance";
|
|
1301
1301
|
OffchainFractionsError["INSUFFICIENT_ALLOWANCE"] = "Insufficient allowance";
|
|
1302
1302
|
})(exports.OffchainFractionsError || (exports.OffchainFractionsError = {}));
|
|
1303
|
-
// Utility to extract the most useful revert reason from
|
|
1304
|
-
function
|
|
1303
|
+
// Utility to extract the most useful revert reason from a viem error object
|
|
1304
|
+
function parseViemError(error) {
|
|
1305
1305
|
if (!error)
|
|
1306
1306
|
return "Unknown error";
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1307
|
+
// Check if it's a viem BaseError
|
|
1308
|
+
if (error instanceof Error) {
|
|
1309
|
+
// For contract revert errors
|
|
1310
|
+
if (error.cause?.reason) {
|
|
1311
|
+
return error.cause.reason;
|
|
1312
|
+
}
|
|
1313
|
+
// For viem's shortMessage
|
|
1314
|
+
if (error.shortMessage) {
|
|
1315
|
+
return error.shortMessage;
|
|
1316
|
+
}
|
|
1317
|
+
// Fallback to regular message
|
|
1318
|
+
if (error.message) {
|
|
1319
|
+
return error.message;
|
|
1315
1320
|
}
|
|
1316
|
-
catch { }
|
|
1317
1321
|
}
|
|
1318
|
-
// Found on MetaMask/Alchemy shape errors
|
|
1319
|
-
if (possibleError?.data?.message)
|
|
1320
|
-
return possibleError.data.message;
|
|
1321
|
-
if (possibleError?.error?.message)
|
|
1322
|
-
return possibleError.error.message;
|
|
1323
|
-
// Standard ethers v5 message
|
|
1324
|
-
if (possibleError?.reason)
|
|
1325
|
-
return possibleError.reason;
|
|
1326
|
-
if (possibleError?.message)
|
|
1327
|
-
return possibleError.message;
|
|
1328
1322
|
return exports.OffchainFractionsError.UNKNOWN_ERROR;
|
|
1329
1323
|
}
|
|
1330
|
-
// Type-guard style helper to ensure a
|
|
1331
|
-
function
|
|
1332
|
-
if (!
|
|
1324
|
+
// Type-guard style helper to ensure a wallet client exists throughout the rest of the function.
|
|
1325
|
+
function assertWalletClient(maybeWalletClient) {
|
|
1326
|
+
if (!maybeWalletClient) {
|
|
1333
1327
|
throw new Error(exports.OffchainFractionsError.SIGNER_NOT_AVAILABLE);
|
|
1334
1328
|
}
|
|
1329
|
+
if (!maybeWalletClient.account) {
|
|
1330
|
+
throw new Error("Wallet client must have an account");
|
|
1331
|
+
}
|
|
1335
1332
|
}
|
|
1336
|
-
function useOffchainFractions(
|
|
1333
|
+
function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
1337
1334
|
// Use dynamic addresses based on chain configuration
|
|
1338
1335
|
const ADDRESSES = getAddresses(CHAIN_ID);
|
|
1339
1336
|
// Framework-agnostic processing flag
|
|
@@ -1341,17 +1338,11 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1341
1338
|
const setIsProcessing = (value) => {
|
|
1342
1339
|
isProcessing = value;
|
|
1343
1340
|
};
|
|
1344
|
-
//
|
|
1345
|
-
function
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
/**
|
|
1350
|
-
* Get the appropriate token contract
|
|
1351
|
-
*/
|
|
1352
|
-
function getTokenContract(tokenAddress) {
|
|
1353
|
-
assertSigner(signer);
|
|
1354
|
-
return new ethers.Contract(tokenAddress, ERC20_ABI, signer);
|
|
1341
|
+
// Helper to assert public client is available
|
|
1342
|
+
function assertPublicClient(maybePublicClient) {
|
|
1343
|
+
if (!maybePublicClient) {
|
|
1344
|
+
throw new Error("Public client not available");
|
|
1345
|
+
}
|
|
1355
1346
|
}
|
|
1356
1347
|
/**
|
|
1357
1348
|
* Check current token allowance for the offchain fractions contract
|
|
@@ -1359,16 +1350,18 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1359
1350
|
* @param tokenAddress The token contract address
|
|
1360
1351
|
*/
|
|
1361
1352
|
async function checkTokenAllowance(owner, tokenAddress) {
|
|
1362
|
-
|
|
1353
|
+
assertPublicClient(publicClient);
|
|
1363
1354
|
try {
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1355
|
+
const allowance = await publicClient.readContract({
|
|
1356
|
+
address: tokenAddress,
|
|
1357
|
+
abi: ERC20_ABI,
|
|
1358
|
+
functionName: "allowance",
|
|
1359
|
+
args: [owner, ADDRESSES.OFFCHAIN_FRACTIONS],
|
|
1360
|
+
});
|
|
1368
1361
|
return allowance;
|
|
1369
1362
|
}
|
|
1370
1363
|
catch (error) {
|
|
1371
|
-
throw new Error(
|
|
1364
|
+
throw new Error(parseViemError(error));
|
|
1372
1365
|
}
|
|
1373
1366
|
}
|
|
1374
1367
|
/**
|
|
@@ -1377,16 +1370,18 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1377
1370
|
* @param tokenAddress The token contract address
|
|
1378
1371
|
*/
|
|
1379
1372
|
async function checkTokenBalance(owner, tokenAddress) {
|
|
1380
|
-
|
|
1373
|
+
assertPublicClient(publicClient);
|
|
1381
1374
|
try {
|
|
1382
|
-
const
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1375
|
+
const balance = await publicClient.readContract({
|
|
1376
|
+
address: tokenAddress,
|
|
1377
|
+
abi: ERC20_ABI,
|
|
1378
|
+
functionName: "balanceOf",
|
|
1379
|
+
args: [owner],
|
|
1380
|
+
});
|
|
1386
1381
|
return balance;
|
|
1387
1382
|
}
|
|
1388
1383
|
catch (error) {
|
|
1389
|
-
throw new Error(
|
|
1384
|
+
throw new Error(parseViemError(error));
|
|
1390
1385
|
}
|
|
1391
1386
|
}
|
|
1392
1387
|
/**
|
|
@@ -1395,18 +1390,25 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1395
1390
|
* @param amount Amount to approve (BigNumber)
|
|
1396
1391
|
*/
|
|
1397
1392
|
async function approveToken(tokenAddress, amount) {
|
|
1398
|
-
|
|
1393
|
+
assertWalletClient(walletClient);
|
|
1394
|
+
assertPublicClient(publicClient);
|
|
1399
1395
|
try {
|
|
1400
|
-
const tokenContract = getTokenContract(tokenAddress);
|
|
1401
|
-
if (!tokenContract)
|
|
1402
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1403
1396
|
setIsProcessing(true);
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1397
|
+
const hash = await walletClient.writeContract({
|
|
1398
|
+
address: tokenAddress,
|
|
1399
|
+
abi: ERC20_ABI,
|
|
1400
|
+
functionName: "approve",
|
|
1401
|
+
args: [ADDRESSES.OFFCHAIN_FRACTIONS, amount],
|
|
1402
|
+
chain: walletClient.chain,
|
|
1403
|
+
account: walletClient.account,
|
|
1404
|
+
});
|
|
1405
|
+
await publicClient.waitForTransactionReceipt({
|
|
1406
|
+
hash,
|
|
1407
|
+
});
|
|
1406
1408
|
return true;
|
|
1407
1409
|
}
|
|
1408
1410
|
catch (error) {
|
|
1409
|
-
throw new Error(
|
|
1411
|
+
throw new Error(parseViemError(error));
|
|
1410
1412
|
}
|
|
1411
1413
|
finally {
|
|
1412
1414
|
setIsProcessing(false);
|
|
@@ -1417,11 +1419,9 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1417
1419
|
* @param params Parameters for creating the fraction
|
|
1418
1420
|
*/
|
|
1419
1421
|
async function createFraction(params) {
|
|
1420
|
-
|
|
1422
|
+
assertWalletClient(walletClient);
|
|
1423
|
+
assertPublicClient(publicClient);
|
|
1421
1424
|
try {
|
|
1422
|
-
const contract = getOffchainFractionsContract();
|
|
1423
|
-
if (!contract)
|
|
1424
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1425
1425
|
setIsProcessing(true);
|
|
1426
1426
|
const { id, token, step, totalSteps, expiration, to, useCounterfactualAddress, minSharesToRaise, closer, } = params;
|
|
1427
1427
|
// Validate parameters
|
|
@@ -1434,22 +1434,55 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1434
1434
|
if (minSharesToRaise > totalSteps) {
|
|
1435
1435
|
throw new Error("minSharesToRaise cannot be greater than totalSteps");
|
|
1436
1436
|
}
|
|
1437
|
-
// Run a
|
|
1437
|
+
// Run a simulation first to surface any revert reason
|
|
1438
1438
|
try {
|
|
1439
|
-
await
|
|
1440
|
-
.
|
|
1441
|
-
|
|
1439
|
+
await publicClient.simulateContract({
|
|
1440
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1441
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1442
|
+
functionName: "createFraction",
|
|
1443
|
+
args: [
|
|
1444
|
+
id,
|
|
1445
|
+
token,
|
|
1446
|
+
step,
|
|
1447
|
+
totalSteps,
|
|
1448
|
+
expiration,
|
|
1449
|
+
to,
|
|
1450
|
+
useCounterfactualAddress,
|
|
1451
|
+
minSharesToRaise,
|
|
1452
|
+
closer,
|
|
1453
|
+
],
|
|
1454
|
+
account: walletClient.account,
|
|
1455
|
+
});
|
|
1442
1456
|
}
|
|
1443
|
-
catch (
|
|
1444
|
-
throw new Error(
|
|
1457
|
+
catch (simulationError) {
|
|
1458
|
+
throw new Error(parseViemError(simulationError));
|
|
1445
1459
|
}
|
|
1446
1460
|
// Execute the transaction
|
|
1447
|
-
const
|
|
1448
|
-
|
|
1449
|
-
|
|
1461
|
+
const hash = await walletClient.writeContract({
|
|
1462
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1463
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1464
|
+
functionName: "createFraction",
|
|
1465
|
+
args: [
|
|
1466
|
+
id,
|
|
1467
|
+
token,
|
|
1468
|
+
step,
|
|
1469
|
+
totalSteps,
|
|
1470
|
+
expiration,
|
|
1471
|
+
to,
|
|
1472
|
+
useCounterfactualAddress,
|
|
1473
|
+
minSharesToRaise,
|
|
1474
|
+
closer,
|
|
1475
|
+
],
|
|
1476
|
+
chain: walletClient.chain,
|
|
1477
|
+
account: walletClient.account,
|
|
1478
|
+
});
|
|
1479
|
+
await publicClient.waitForTransactionReceipt({
|
|
1480
|
+
hash,
|
|
1481
|
+
});
|
|
1482
|
+
return hash;
|
|
1450
1483
|
}
|
|
1451
1484
|
catch (error) {
|
|
1452
|
-
throw new Error(
|
|
1485
|
+
throw new Error(parseViemError(error));
|
|
1453
1486
|
}
|
|
1454
1487
|
finally {
|
|
1455
1488
|
setIsProcessing(false);
|
|
@@ -1460,11 +1493,9 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1460
1493
|
* @param params Parameters for buying fractions
|
|
1461
1494
|
*/
|
|
1462
1495
|
async function buyFractions(params) {
|
|
1463
|
-
|
|
1496
|
+
assertWalletClient(walletClient);
|
|
1497
|
+
assertPublicClient(publicClient);
|
|
1464
1498
|
try {
|
|
1465
|
-
const contract = getOffchainFractionsContract();
|
|
1466
|
-
if (!contract)
|
|
1467
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1468
1499
|
setIsProcessing(true);
|
|
1469
1500
|
const { creator, id, stepsToBuy, minStepsToBuy, refundTo, creditTo, useCounterfactualAddressForRefund, } = params;
|
|
1470
1501
|
// Validate parameters
|
|
@@ -1480,7 +1511,10 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1480
1511
|
// Get fraction data to calculate required amount
|
|
1481
1512
|
const fractionData = await getFraction(creator, id);
|
|
1482
1513
|
const requiredAmount = stepsToBuy * fractionData.step;
|
|
1483
|
-
const owner =
|
|
1514
|
+
const owner = walletClient.account?.address;
|
|
1515
|
+
if (!owner) {
|
|
1516
|
+
throw new Error("No account found in wallet client");
|
|
1517
|
+
}
|
|
1484
1518
|
// Check token balance
|
|
1485
1519
|
const balance = await checkTokenBalance(owner, fractionData.token);
|
|
1486
1520
|
if (balance < requiredAmount) {
|
|
@@ -1489,28 +1523,63 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1489
1523
|
// Check and approve tokens if necessary
|
|
1490
1524
|
const allowance = await checkTokenAllowance(owner, fractionData.token);
|
|
1491
1525
|
if (allowance < requiredAmount) {
|
|
1492
|
-
const
|
|
1493
|
-
|
|
1494
|
-
|
|
1526
|
+
const approveHash = await walletClient.writeContract({
|
|
1527
|
+
address: fractionData.token,
|
|
1528
|
+
abi: ERC20_ABI,
|
|
1529
|
+
functionName: "approve",
|
|
1530
|
+
args: [ADDRESSES.OFFCHAIN_FRACTIONS, requiredAmount],
|
|
1531
|
+
chain: walletClient.chain,
|
|
1532
|
+
account: walletClient.account,
|
|
1533
|
+
});
|
|
1534
|
+
await publicClient.waitForTransactionReceipt({
|
|
1535
|
+
hash: approveHash,
|
|
1536
|
+
});
|
|
1495
1537
|
}
|
|
1496
|
-
// Run a
|
|
1538
|
+
// Run a simulation first to surface any revert reason
|
|
1497
1539
|
try {
|
|
1498
|
-
await
|
|
1499
|
-
.
|
|
1500
|
-
|
|
1501
|
-
|
|
1540
|
+
await publicClient.simulateContract({
|
|
1541
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1542
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1543
|
+
functionName: "buyFractions",
|
|
1544
|
+
args: [
|
|
1545
|
+
creator,
|
|
1546
|
+
id,
|
|
1547
|
+
stepsToBuy,
|
|
1548
|
+
minStepsToBuy,
|
|
1549
|
+
refundTo,
|
|
1550
|
+
creditTo,
|
|
1551
|
+
useCounterfactualAddressForRefund,
|
|
1552
|
+
],
|
|
1553
|
+
account: walletClient.account,
|
|
1502
1554
|
});
|
|
1503
1555
|
}
|
|
1504
|
-
catch (
|
|
1505
|
-
throw new Error(
|
|
1556
|
+
catch (simulationError) {
|
|
1557
|
+
throw new Error(parseViemError(simulationError));
|
|
1506
1558
|
}
|
|
1507
1559
|
// Execute the transaction
|
|
1508
|
-
const
|
|
1509
|
-
|
|
1510
|
-
|
|
1560
|
+
const hash = await walletClient.writeContract({
|
|
1561
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1562
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1563
|
+
functionName: "buyFractions",
|
|
1564
|
+
args: [
|
|
1565
|
+
creator,
|
|
1566
|
+
id,
|
|
1567
|
+
stepsToBuy,
|
|
1568
|
+
minStepsToBuy,
|
|
1569
|
+
refundTo,
|
|
1570
|
+
creditTo,
|
|
1571
|
+
useCounterfactualAddressForRefund,
|
|
1572
|
+
],
|
|
1573
|
+
chain: walletClient.chain,
|
|
1574
|
+
account: walletClient.account,
|
|
1575
|
+
});
|
|
1576
|
+
await publicClient.waitForTransactionReceipt({
|
|
1577
|
+
hash,
|
|
1578
|
+
});
|
|
1579
|
+
return hash;
|
|
1511
1580
|
}
|
|
1512
1581
|
catch (error) {
|
|
1513
|
-
throw new Error(
|
|
1582
|
+
throw new Error(parseViemError(error));
|
|
1514
1583
|
}
|
|
1515
1584
|
finally {
|
|
1516
1585
|
setIsProcessing(false);
|
|
@@ -1523,11 +1592,9 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1523
1592
|
* @param id The unique identifier of the fraction sale
|
|
1524
1593
|
*/
|
|
1525
1594
|
async function claimRefund(user, creator, id) {
|
|
1526
|
-
|
|
1595
|
+
assertWalletClient(walletClient);
|
|
1596
|
+
assertPublicClient(publicClient);
|
|
1527
1597
|
try {
|
|
1528
|
-
const contract = getOffchainFractionsContract();
|
|
1529
|
-
if (!contract)
|
|
1530
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1531
1598
|
setIsProcessing(true);
|
|
1532
1599
|
// Normalize addresses to lowercase for consistency
|
|
1533
1600
|
const normalizedUser = user?.toLowerCase();
|
|
@@ -1547,37 +1614,52 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1547
1614
|
if (!normalizedUser || !normalizedCreator || !id) {
|
|
1548
1615
|
throw new Error(exports.OffchainFractionsError.INVALID_PARAMETERS);
|
|
1549
1616
|
}
|
|
1550
|
-
const owner =
|
|
1617
|
+
const owner = walletClient.account?.address;
|
|
1618
|
+
if (!owner) {
|
|
1619
|
+
throw new Error("No account found in wallet client");
|
|
1620
|
+
}
|
|
1551
1621
|
// Check if user has steps purchased
|
|
1552
1622
|
const userSteps = await getStepsPurchased(user, creator, id);
|
|
1553
1623
|
if (userSteps === 0n) {
|
|
1554
1624
|
throw new Error("No steps purchased for this fraction");
|
|
1555
1625
|
}
|
|
1556
|
-
// Run a
|
|
1626
|
+
// Run a simulation first to surface any revert reason
|
|
1557
1627
|
try {
|
|
1558
|
-
console.log("Calling claimRefund
|
|
1628
|
+
console.log("Calling claimRefund simulation with:", {
|
|
1559
1629
|
user,
|
|
1560
1630
|
creator,
|
|
1561
1631
|
id,
|
|
1562
1632
|
from: owner,
|
|
1563
1633
|
contractMethod: "claimRefund",
|
|
1564
1634
|
});
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1635
|
+
await publicClient.simulateContract({
|
|
1636
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1637
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1638
|
+
functionName: "claimRefund",
|
|
1639
|
+
args: [user, creator, id],
|
|
1640
|
+
account: walletClient.account,
|
|
1568
1641
|
});
|
|
1569
1642
|
}
|
|
1570
|
-
catch (
|
|
1571
|
-
console.error("
|
|
1572
|
-
throw new Error(
|
|
1643
|
+
catch (simulationError) {
|
|
1644
|
+
console.error("Simulation failed:", simulationError);
|
|
1645
|
+
throw new Error(parseViemError(simulationError));
|
|
1573
1646
|
}
|
|
1574
|
-
// Execute the transaction
|
|
1575
|
-
const
|
|
1576
|
-
|
|
1577
|
-
|
|
1647
|
+
// Execute the transaction
|
|
1648
|
+
const hash = await walletClient.writeContract({
|
|
1649
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1650
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1651
|
+
functionName: "claimRefund",
|
|
1652
|
+
args: [user, creator, id],
|
|
1653
|
+
chain: walletClient.chain,
|
|
1654
|
+
account: walletClient.account,
|
|
1655
|
+
});
|
|
1656
|
+
await publicClient.waitForTransactionReceipt({
|
|
1657
|
+
hash,
|
|
1658
|
+
});
|
|
1659
|
+
return hash;
|
|
1578
1660
|
}
|
|
1579
1661
|
catch (error) {
|
|
1580
|
-
throw new Error(
|
|
1662
|
+
throw new Error(parseViemError(error));
|
|
1581
1663
|
}
|
|
1582
1664
|
finally {
|
|
1583
1665
|
setIsProcessing(false);
|
|
@@ -1589,33 +1671,47 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1589
1671
|
* @param id The unique identifier of the fraction sale to close
|
|
1590
1672
|
*/
|
|
1591
1673
|
async function closeFraction(creator, id) {
|
|
1592
|
-
|
|
1674
|
+
assertWalletClient(walletClient);
|
|
1675
|
+
assertPublicClient(publicClient);
|
|
1593
1676
|
try {
|
|
1594
|
-
const contract = getOffchainFractionsContract();
|
|
1595
|
-
if (!contract)
|
|
1596
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1597
1677
|
setIsProcessing(true);
|
|
1598
1678
|
// Validate parameters
|
|
1599
1679
|
if (!creator || !id) {
|
|
1600
1680
|
throw new Error(exports.OffchainFractionsError.INVALID_PARAMETERS);
|
|
1601
1681
|
}
|
|
1602
|
-
const owner =
|
|
1603
|
-
|
|
1682
|
+
const owner = walletClient.account?.address;
|
|
1683
|
+
if (!owner) {
|
|
1684
|
+
throw new Error("No account found in wallet client");
|
|
1685
|
+
}
|
|
1686
|
+
// Run a simulation first to surface any revert reason
|
|
1604
1687
|
try {
|
|
1605
|
-
await
|
|
1606
|
-
|
|
1688
|
+
await publicClient.simulateContract({
|
|
1689
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1690
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1691
|
+
functionName: "closeFraction",
|
|
1692
|
+
args: [creator, id],
|
|
1693
|
+
account: walletClient.account,
|
|
1607
1694
|
});
|
|
1608
1695
|
}
|
|
1609
|
-
catch (
|
|
1610
|
-
throw new Error(
|
|
1696
|
+
catch (simulationError) {
|
|
1697
|
+
throw new Error(parseViemError(simulationError));
|
|
1611
1698
|
}
|
|
1612
1699
|
// Execute the transaction
|
|
1613
|
-
const
|
|
1614
|
-
|
|
1615
|
-
|
|
1700
|
+
const hash = await walletClient.writeContract({
|
|
1701
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1702
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1703
|
+
functionName: "closeFraction",
|
|
1704
|
+
args: [creator, id],
|
|
1705
|
+
chain: walletClient.chain,
|
|
1706
|
+
account: walletClient.account,
|
|
1707
|
+
});
|
|
1708
|
+
await publicClient.waitForTransactionReceipt({
|
|
1709
|
+
hash,
|
|
1710
|
+
});
|
|
1711
|
+
return hash;
|
|
1616
1712
|
}
|
|
1617
1713
|
catch (error) {
|
|
1618
|
-
throw new Error(
|
|
1714
|
+
throw new Error(parseViemError(error));
|
|
1619
1715
|
}
|
|
1620
1716
|
finally {
|
|
1621
1717
|
setIsProcessing(false);
|
|
@@ -1627,12 +1723,14 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1627
1723
|
* @param id The unique identifier of the fraction sale
|
|
1628
1724
|
*/
|
|
1629
1725
|
async function getFraction(creator, id) {
|
|
1630
|
-
|
|
1631
|
-
try {
|
|
1632
|
-
const
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1726
|
+
assertPublicClient(publicClient);
|
|
1727
|
+
try {
|
|
1728
|
+
const result = (await publicClient.readContract({
|
|
1729
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1730
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1731
|
+
functionName: "getFraction",
|
|
1732
|
+
args: [creator, id],
|
|
1733
|
+
}));
|
|
1636
1734
|
return {
|
|
1637
1735
|
token: result.token,
|
|
1638
1736
|
expiration: Number(result.expiration),
|
|
@@ -1648,7 +1746,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1648
1746
|
};
|
|
1649
1747
|
}
|
|
1650
1748
|
catch (error) {
|
|
1651
|
-
throw new Error(
|
|
1749
|
+
throw new Error(parseViemError(error));
|
|
1652
1750
|
}
|
|
1653
1751
|
}
|
|
1654
1752
|
/**
|
|
@@ -1658,24 +1756,26 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1658
1756
|
* @param id The unique identifier of the fraction sale
|
|
1659
1757
|
*/
|
|
1660
1758
|
async function getStepsPurchased(user, creator, id) {
|
|
1661
|
-
|
|
1759
|
+
assertPublicClient(publicClient);
|
|
1662
1760
|
try {
|
|
1663
|
-
const contract = getOffchainFractionsContract();
|
|
1664
|
-
if (!contract)
|
|
1665
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1666
1761
|
// Debug logging
|
|
1667
1762
|
console.log("getStepsPurchased parameters:", {
|
|
1668
1763
|
user,
|
|
1669
1764
|
creator,
|
|
1670
1765
|
id,
|
|
1671
|
-
contractAddress:
|
|
1766
|
+
contractAddress: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1672
1767
|
});
|
|
1673
|
-
const result = await
|
|
1768
|
+
const result = (await publicClient.readContract({
|
|
1769
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1770
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1771
|
+
functionName: "stepsPurchased",
|
|
1772
|
+
args: [user, creator, id],
|
|
1773
|
+
}));
|
|
1674
1774
|
console.log("getStepsPurchased result:", result.toString());
|
|
1675
1775
|
return result;
|
|
1676
1776
|
}
|
|
1677
1777
|
catch (error) {
|
|
1678
|
-
throw new Error(
|
|
1778
|
+
throw new Error(parseViemError(error));
|
|
1679
1779
|
}
|
|
1680
1780
|
}
|
|
1681
1781
|
/**
|
|
@@ -1683,16 +1783,18 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1683
1783
|
* @returns The wildcard operator address that can perform refunds for any user
|
|
1684
1784
|
*/
|
|
1685
1785
|
async function getRefundWildcardOperator() {
|
|
1686
|
-
|
|
1687
|
-
try {
|
|
1688
|
-
const
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1786
|
+
assertPublicClient(publicClient);
|
|
1787
|
+
try {
|
|
1788
|
+
const result = (await publicClient.readContract({
|
|
1789
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1790
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1791
|
+
functionName: "REFUND_WILDCARD_OPERATOR",
|
|
1792
|
+
args: [],
|
|
1793
|
+
}));
|
|
1692
1794
|
return result;
|
|
1693
1795
|
}
|
|
1694
1796
|
catch (error) {
|
|
1695
|
-
throw new Error(
|
|
1797
|
+
throw new Error(parseViemError(error));
|
|
1696
1798
|
}
|
|
1697
1799
|
}
|
|
1698
1800
|
/**
|
|
@@ -1702,19 +1804,21 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1702
1804
|
* @param id The unique identifier of the fraction sale
|
|
1703
1805
|
*/
|
|
1704
1806
|
async function getRefundDetails(user, creator, id) {
|
|
1705
|
-
|
|
1706
|
-
try {
|
|
1707
|
-
const
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1807
|
+
assertPublicClient(publicClient);
|
|
1808
|
+
try {
|
|
1809
|
+
const result = (await publicClient.readContract({
|
|
1810
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1811
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1812
|
+
functionName: "getRefundDetails",
|
|
1813
|
+
args: [user, creator, id],
|
|
1814
|
+
}));
|
|
1711
1815
|
return {
|
|
1712
1816
|
refundTo: result.refundTo,
|
|
1713
1817
|
useCounterfactualAddress: result.useCounterfactualAddress,
|
|
1714
1818
|
};
|
|
1715
1819
|
}
|
|
1716
1820
|
catch (error) {
|
|
1717
|
-
throw new Error(
|
|
1821
|
+
throw new Error(parseViemError(error));
|
|
1718
1822
|
}
|
|
1719
1823
|
}
|
|
1720
1824
|
/**
|
|
@@ -1725,35 +1829,57 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1725
1829
|
* @param useCounterfactualAddress Whether to use counterfactual address for refunds
|
|
1726
1830
|
*/
|
|
1727
1831
|
async function setRefundDetails(creator, id, refundTo, useCounterfactualAddress) {
|
|
1728
|
-
|
|
1832
|
+
assertWalletClient(walletClient);
|
|
1833
|
+
assertPublicClient(publicClient);
|
|
1729
1834
|
try {
|
|
1730
|
-
const contract = getOffchainFractionsContract();
|
|
1731
|
-
if (!contract)
|
|
1732
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1733
1835
|
setIsProcessing(true);
|
|
1734
1836
|
// Validate parameters
|
|
1735
1837
|
if (!creator || !id || !refundTo) {
|
|
1736
1838
|
throw new Error(exports.OffchainFractionsError.INVALID_PARAMETERS);
|
|
1737
1839
|
}
|
|
1738
|
-
const owner =
|
|
1739
|
-
|
|
1840
|
+
const owner = walletClient.account?.address;
|
|
1841
|
+
if (!owner) {
|
|
1842
|
+
throw new Error("No account found in wallet client");
|
|
1843
|
+
}
|
|
1844
|
+
// Run a simulation first to surface any revert reason
|
|
1740
1845
|
try {
|
|
1741
|
-
await
|
|
1742
|
-
.
|
|
1743
|
-
|
|
1744
|
-
|
|
1846
|
+
await publicClient.simulateContract({
|
|
1847
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1848
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1849
|
+
functionName: "setRefundDetails",
|
|
1850
|
+
args: [
|
|
1851
|
+
creator,
|
|
1852
|
+
id,
|
|
1853
|
+
refundTo,
|
|
1854
|
+
useCounterfactualAddress,
|
|
1855
|
+
],
|
|
1856
|
+
account: walletClient.account,
|
|
1745
1857
|
});
|
|
1746
1858
|
}
|
|
1747
|
-
catch (
|
|
1748
|
-
throw new Error(
|
|
1859
|
+
catch (simulationError) {
|
|
1860
|
+
throw new Error(parseViemError(simulationError));
|
|
1749
1861
|
}
|
|
1750
1862
|
// Execute the transaction
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1753
|
-
|
|
1863
|
+
const hash = await walletClient.writeContract({
|
|
1864
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1865
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1866
|
+
functionName: "setRefundDetails",
|
|
1867
|
+
args: [
|
|
1868
|
+
creator,
|
|
1869
|
+
id,
|
|
1870
|
+
refundTo,
|
|
1871
|
+
useCounterfactualAddress,
|
|
1872
|
+
],
|
|
1873
|
+
chain: walletClient.chain,
|
|
1874
|
+
account: walletClient.account,
|
|
1875
|
+
});
|
|
1876
|
+
await publicClient.waitForTransactionReceipt({
|
|
1877
|
+
hash,
|
|
1878
|
+
});
|
|
1879
|
+
return hash;
|
|
1754
1880
|
}
|
|
1755
1881
|
catch (error) {
|
|
1756
|
-
throw new Error(
|
|
1882
|
+
throw new Error(parseViemError(error));
|
|
1757
1883
|
}
|
|
1758
1884
|
finally {
|
|
1759
1885
|
setIsProcessing(false);
|
|
@@ -1765,35 +1891,47 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1765
1891
|
* @param isApproved Whether to approve or revoke the operator
|
|
1766
1892
|
*/
|
|
1767
1893
|
async function setRefundOperatorStatus(refundOperator, isApproved) {
|
|
1768
|
-
|
|
1894
|
+
assertWalletClient(walletClient);
|
|
1895
|
+
assertPublicClient(publicClient);
|
|
1769
1896
|
try {
|
|
1770
|
-
const contract = getOffchainFractionsContract();
|
|
1771
|
-
if (!contract)
|
|
1772
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1773
1897
|
setIsProcessing(true);
|
|
1774
1898
|
// Validate parameters
|
|
1775
1899
|
if (!refundOperator) {
|
|
1776
1900
|
throw new Error(exports.OffchainFractionsError.INVALID_PARAMETERS);
|
|
1777
1901
|
}
|
|
1778
|
-
const owner =
|
|
1779
|
-
|
|
1902
|
+
const owner = walletClient.account?.address;
|
|
1903
|
+
if (!owner) {
|
|
1904
|
+
throw new Error("No account found in wallet client");
|
|
1905
|
+
}
|
|
1906
|
+
// Run a simulation first to surface any revert reason
|
|
1780
1907
|
try {
|
|
1781
|
-
await
|
|
1782
|
-
.
|
|
1783
|
-
|
|
1784
|
-
|
|
1908
|
+
await publicClient.simulateContract({
|
|
1909
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1910
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1911
|
+
functionName: "setRefundOperatorStatus",
|
|
1912
|
+
args: [refundOperator, isApproved],
|
|
1913
|
+
account: walletClient.account,
|
|
1785
1914
|
});
|
|
1786
1915
|
}
|
|
1787
|
-
catch (
|
|
1788
|
-
throw new Error(
|
|
1916
|
+
catch (simulationError) {
|
|
1917
|
+
throw new Error(parseViemError(simulationError));
|
|
1789
1918
|
}
|
|
1790
1919
|
// Execute the transaction
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
|
|
1920
|
+
const hash = await walletClient.writeContract({
|
|
1921
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1922
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1923
|
+
functionName: "setRefundOperatorStatus",
|
|
1924
|
+
args: [refundOperator, isApproved],
|
|
1925
|
+
chain: walletClient.chain,
|
|
1926
|
+
account: walletClient.account,
|
|
1927
|
+
});
|
|
1928
|
+
await publicClient.waitForTransactionReceipt({
|
|
1929
|
+
hash,
|
|
1930
|
+
});
|
|
1931
|
+
return hash;
|
|
1794
1932
|
}
|
|
1795
1933
|
catch (error) {
|
|
1796
|
-
throw new Error(
|
|
1934
|
+
throw new Error(parseViemError(error));
|
|
1797
1935
|
}
|
|
1798
1936
|
finally {
|
|
1799
1937
|
setIsProcessing(false);
|
|
@@ -1805,16 +1943,18 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1805
1943
|
* @param refundOperator The refund operator address
|
|
1806
1944
|
*/
|
|
1807
1945
|
async function isRefundOperatorApproved(user, refundOperator) {
|
|
1808
|
-
|
|
1809
|
-
try {
|
|
1810
|
-
const
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1946
|
+
assertPublicClient(publicClient);
|
|
1947
|
+
try {
|
|
1948
|
+
const result = (await publicClient.readContract({
|
|
1949
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1950
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1951
|
+
functionName: "isRefundOperatorApproved",
|
|
1952
|
+
args: [user, refundOperator],
|
|
1953
|
+
}));
|
|
1814
1954
|
return result;
|
|
1815
1955
|
}
|
|
1816
1956
|
catch (error) {
|
|
1817
|
-
throw new Error(
|
|
1957
|
+
throw new Error(parseViemError(error));
|
|
1818
1958
|
}
|
|
1819
1959
|
}
|
|
1820
1960
|
/**
|
|
@@ -1823,16 +1963,18 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1823
1963
|
* @param refundOperator The refund operator address
|
|
1824
1964
|
*/
|
|
1825
1965
|
async function getRefundApprovalStatus(user, refundOperator) {
|
|
1826
|
-
|
|
1827
|
-
try {
|
|
1828
|
-
const
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1966
|
+
assertPublicClient(publicClient);
|
|
1967
|
+
try {
|
|
1968
|
+
const result = (await publicClient.readContract({
|
|
1969
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
1970
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
1971
|
+
functionName: "refundApprovals",
|
|
1972
|
+
args: [user, refundOperator],
|
|
1973
|
+
}));
|
|
1832
1974
|
return result.isApproved;
|
|
1833
1975
|
}
|
|
1834
1976
|
catch (error) {
|
|
1835
|
-
throw new Error(
|
|
1977
|
+
throw new Error(parseViemError(error));
|
|
1836
1978
|
}
|
|
1837
1979
|
}
|
|
1838
1980
|
/**
|
|
@@ -1846,7 +1988,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1846
1988
|
return Date.now() / 1000 > fraction.expiration;
|
|
1847
1989
|
}
|
|
1848
1990
|
catch (error) {
|
|
1849
|
-
throw new Error(
|
|
1991
|
+
throw new Error(parseViemError(error));
|
|
1850
1992
|
}
|
|
1851
1993
|
}
|
|
1852
1994
|
/**
|
|
@@ -1860,7 +2002,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1860
2002
|
return fraction.soldSteps >= fraction.minSharesToRaise;
|
|
1861
2003
|
}
|
|
1862
2004
|
catch (error) {
|
|
1863
|
-
throw new Error(
|
|
2005
|
+
throw new Error(parseViemError(error));
|
|
1864
2006
|
}
|
|
1865
2007
|
}
|
|
1866
2008
|
/**
|
|
@@ -1874,7 +2016,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1874
2016
|
return fraction.soldSteps >= fraction.totalSteps;
|
|
1875
2017
|
}
|
|
1876
2018
|
catch (error) {
|
|
1877
|
-
throw new Error(
|
|
2019
|
+
throw new Error(parseViemError(error));
|
|
1878
2020
|
}
|
|
1879
2021
|
}
|
|
1880
2022
|
/**
|
|
@@ -1888,7 +2030,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1888
2030
|
return fraction.soldSteps * fraction.step;
|
|
1889
2031
|
}
|
|
1890
2032
|
catch (error) {
|
|
1891
|
-
throw new Error(
|
|
2033
|
+
throw new Error(parseViemError(error));
|
|
1892
2034
|
}
|
|
1893
2035
|
}
|
|
1894
2036
|
/**
|
|
@@ -1902,7 +2044,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1902
2044
|
return fraction.totalSteps - fraction.soldSteps;
|
|
1903
2045
|
}
|
|
1904
2046
|
catch (error) {
|
|
1905
|
-
throw new Error(
|
|
2047
|
+
throw new Error(parseViemError(error));
|
|
1906
2048
|
}
|
|
1907
2049
|
}
|
|
1908
2050
|
/**
|
|
@@ -1911,20 +2053,31 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1911
2053
|
* @param ethPriceInUSD Current ETH price in USD (for cost estimation)
|
|
1912
2054
|
*/
|
|
1913
2055
|
async function estimateGasForCreateFraction(params, ethPriceInUSD) {
|
|
1914
|
-
|
|
2056
|
+
assertWalletClient(walletClient);
|
|
2057
|
+
assertPublicClient(publicClient);
|
|
1915
2058
|
try {
|
|
1916
|
-
const contract = getOffchainFractionsContract();
|
|
1917
|
-
if (!contract)
|
|
1918
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1919
2059
|
const { id, token, step, totalSteps, expiration, to, useCounterfactualAddress, minSharesToRaise, closer, } = params;
|
|
1920
|
-
const
|
|
1921
|
-
|
|
1922
|
-
if (gasPrice === 0n) {
|
|
2060
|
+
const gasPrice = await publicClient.getGasPrice();
|
|
2061
|
+
if (!gasPrice) {
|
|
1923
2062
|
throw new Error("Could not fetch gas price to estimate cost.");
|
|
1924
2063
|
}
|
|
1925
|
-
const estimatedGas = await
|
|
1926
|
-
.
|
|
1927
|
-
|
|
2064
|
+
const estimatedGas = await publicClient.estimateContractGas({
|
|
2065
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
2066
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
2067
|
+
functionName: "createFraction",
|
|
2068
|
+
args: [
|
|
2069
|
+
id,
|
|
2070
|
+
token,
|
|
2071
|
+
step,
|
|
2072
|
+
totalSteps,
|
|
2073
|
+
expiration,
|
|
2074
|
+
to,
|
|
2075
|
+
useCounterfactualAddress,
|
|
2076
|
+
minSharesToRaise,
|
|
2077
|
+
closer,
|
|
2078
|
+
],
|
|
2079
|
+
account: walletClient.account,
|
|
2080
|
+
});
|
|
1928
2081
|
const estimatedCost = estimatedGas * gasPrice;
|
|
1929
2082
|
if (ethPriceInUSD) {
|
|
1930
2083
|
const estimatedCostInEth = viem.formatEther(estimatedCost);
|
|
@@ -1936,7 +2089,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1936
2089
|
}
|
|
1937
2090
|
}
|
|
1938
2091
|
catch (error) {
|
|
1939
|
-
throw new Error(
|
|
2092
|
+
throw new Error(parseViemError(error));
|
|
1940
2093
|
}
|
|
1941
2094
|
}
|
|
1942
2095
|
/**
|
|
@@ -1945,20 +2098,29 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1945
2098
|
* @param ethPriceInUSD Current ETH price in USD (for cost estimation)
|
|
1946
2099
|
*/
|
|
1947
2100
|
async function estimateGasForBuyFractions(params, ethPriceInUSD) {
|
|
1948
|
-
|
|
2101
|
+
assertWalletClient(walletClient);
|
|
2102
|
+
assertPublicClient(publicClient);
|
|
1949
2103
|
try {
|
|
1950
|
-
const contract = getOffchainFractionsContract();
|
|
1951
|
-
if (!contract)
|
|
1952
|
-
throw new Error(exports.OffchainFractionsError.CONTRACT_NOT_AVAILABLE);
|
|
1953
2104
|
const { creator, id, stepsToBuy, minStepsToBuy, refundTo, creditTo, useCounterfactualAddressForRefund, } = params;
|
|
1954
|
-
const
|
|
1955
|
-
|
|
1956
|
-
if (gasPrice === 0n) {
|
|
2105
|
+
const gasPrice = await publicClient.getGasPrice();
|
|
2106
|
+
if (!gasPrice) {
|
|
1957
2107
|
throw new Error("Could not fetch gas price to estimate cost.");
|
|
1958
2108
|
}
|
|
1959
|
-
const estimatedGas = await
|
|
1960
|
-
.
|
|
1961
|
-
|
|
2109
|
+
const estimatedGas = await publicClient.estimateContractGas({
|
|
2110
|
+
address: ADDRESSES.OFFCHAIN_FRACTIONS,
|
|
2111
|
+
abi: OFFCHAIN_FRACTIONS_ABI,
|
|
2112
|
+
functionName: "buyFractions",
|
|
2113
|
+
args: [
|
|
2114
|
+
creator,
|
|
2115
|
+
id,
|
|
2116
|
+
stepsToBuy,
|
|
2117
|
+
minStepsToBuy,
|
|
2118
|
+
refundTo,
|
|
2119
|
+
creditTo,
|
|
2120
|
+
useCounterfactualAddressForRefund,
|
|
2121
|
+
],
|
|
2122
|
+
account: walletClient.account,
|
|
2123
|
+
});
|
|
1962
2124
|
const estimatedCost = estimatedGas * gasPrice;
|
|
1963
2125
|
if (ethPriceInUSD) {
|
|
1964
2126
|
const estimatedCostInEth = viem.formatEther(estimatedCost);
|
|
@@ -1970,7 +2132,7 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
1970
2132
|
}
|
|
1971
2133
|
}
|
|
1972
2134
|
catch (error) {
|
|
1973
|
-
throw new Error(
|
|
2135
|
+
throw new Error(parseViemError(error));
|
|
1974
2136
|
}
|
|
1975
2137
|
}
|
|
1976
2138
|
return {
|
|
@@ -2007,8 +2169,8 @@ function useOffchainFractions(signer, CHAIN_ID) {
|
|
|
2007
2169
|
return isProcessing;
|
|
2008
2170
|
},
|
|
2009
2171
|
addresses: ADDRESSES,
|
|
2010
|
-
//
|
|
2011
|
-
isSignerAvailable: !!
|
|
2172
|
+
// Wallet client availability
|
|
2173
|
+
isSignerAvailable: !!walletClient,
|
|
2012
2174
|
};
|
|
2013
2175
|
}
|
|
2014
2176
|
|
|
@@ -3433,4 +3595,4 @@ exports.regionMetadata = regionMetadata;
|
|
|
3433
3595
|
exports.usStates = usStates;
|
|
3434
3596
|
exports.useForwarder = useForwarder;
|
|
3435
3597
|
exports.useOffchainFractions = useOffchainFractions;
|
|
3436
|
-
//# sourceMappingURL=farms-router-
|
|
3598
|
+
//# sourceMappingURL=farms-router-CuZE5YJ_.js.map
|