diff --git a/.env.local b/.env.local index b3b54db..92055a5 100644 --- a/.env.local +++ b/.env.local @@ -7,4 +7,7 @@ VITE_OAUTH_CLIENT_UUID=f1f02e3d-c193-4438-b5fb-a27ef2f3a268 VITE_OAUTH_CLIENT_REDIRECT_URI=http://localhost:3000/oauth/callback # Your sale contract address -VITE_SALE_CONTRACT_ADDRESS=0x439A7E681A71B1F3297e2c1b9c35bf226Ee24809 \ No newline at end of file +VITE_SALE_CONTRACT_ADDRESS=0x51BcE35d57833253EAccd6901e95eb6772aFfc8D + +# Address of the payment token +VITE_PAYMENT_TOKEN_ADDRESS=0x036CbD53842c5426634e7929541eC2318f3dCF7e # USDC diff --git a/README.md b/README.md index dbd1ba3..c0e0db4 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,15 @@ pnpm dev The app will be available at `http://localhost:3000`. +The example uses a [SettlementSale](https://github.com/sunrisedotdev/sonar/blob/main/contracts/src/SettlementSale.sol) contract on Base Sepolia. + +In order to test committing funds, you will need to have USDC to commit and ETH to pay for the gas. + +Faucets: + +- USDC: +- ETH: + ## What This Example Demonstrates - **Provider setup** — configuring `SonarProvider` with wagmi and React Query diff --git a/src/ExampleSaleABI.ts b/src/ExampleSaleABI.ts deleted file mode 100644 index 0a96343..0000000 --- a/src/ExampleSaleABI.ts +++ /dev/null @@ -1,343 +0,0 @@ -export const examplSaleABI = [ - { - type: "constructor", - inputs: [ - { - name: "init", - type: "tuple", - internalType: "struct ExampleSale.Init", - components: [ - { name: "saleUUID", type: "bytes16", internalType: "bytes16" }, - { name: "purchasePermitSigner", type: "address", internalType: "address" }, - ], - }, - ], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "DEFAULT_ADMIN_ROLE", - inputs: [], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "MAX_ADDRESSES_PER_ENTITY", - inputs: [], - outputs: [{ name: "", type: "uint8", internalType: "uint8" }], - stateMutability: "view", - }, - { - type: "function", - name: "PURCHASE_PERMIT_SIGNER_ROLE", - inputs: [], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "amountByAddress", - inputs: [{ name: "", type: "address", internalType: "address" }], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "amountByEntity", - inputs: [{ name: "", type: "bytes16", internalType: "bytes16" }], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "entityByAddress", - inputs: [{ name: "addr", type: "address", internalType: "address" }], - outputs: [{ name: "", type: "bytes16", internalType: "bytes16" }], - stateMutability: "view", - }, - { - type: "function", - name: "entityIDByAddress", - inputs: [{ name: "", type: "address", internalType: "address" }], - outputs: [{ name: "", type: "bytes16", internalType: "bytes16" }], - stateMutability: "view", - }, - { - type: "function", - name: "getEntityAddressCount", - inputs: [{ name: "entityID", type: "bytes16", internalType: "bytes16" }], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "getEntityAddresses", - inputs: [{ name: "entityID", type: "bytes16", internalType: "bytes16" }], - outputs: [{ name: "", type: "address[]", internalType: "address[]" }], - stateMutability: "view", - }, - { - type: "function", - name: "getEntityPurchaseBreakdown", - inputs: [{ name: "entityID", type: "bytes16", internalType: "bytes16" }], - outputs: [ - { - name: "purchases", - type: "tuple[]", - internalType: "struct ExampleSale.AddressPurchase[]", - components: [ - { name: "addr", type: "address", internalType: "address" }, - { name: "amount", type: "uint256", internalType: "uint256" }, - ], - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "getRoleAdmin", - inputs: [{ name: "role", type: "bytes32", internalType: "bytes32" }], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "getRoleMember", - inputs: [ - { name: "role", type: "bytes32", internalType: "bytes32" }, - { name: "index", type: "uint256", internalType: "uint256" }, - ], - outputs: [{ name: "", type: "address", internalType: "address" }], - stateMutability: "view", - }, - { - type: "function", - name: "getRoleMemberCount", - inputs: [{ name: "role", type: "bytes32", internalType: "bytes32" }], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "grantRole", - inputs: [ - { name: "role", type: "bytes32", internalType: "bytes32" }, - { name: "account", type: "address", internalType: "address" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "hasRole", - inputs: [ - { name: "role", type: "bytes32", internalType: "bytes32" }, - { name: "account", type: "address", internalType: "address" }, - ], - outputs: [{ name: "", type: "bool", internalType: "bool" }], - stateMutability: "view", - }, - { - type: "function", - name: "purchase", - inputs: [ - { name: "amount", type: "uint256", internalType: "uint256" }, - { - name: "purchasePermit", - type: "tuple", - internalType: "struct PurchasePermitV3", - components: [ - { name: "saleSpecificEntityID", type: "bytes16", internalType: "bytes16" }, - { name: "saleUUID", type: "bytes16", internalType: "bytes16" }, - { name: "wallet", type: "address", internalType: "address" }, - { name: "expiresAt", type: "uint64", internalType: "uint64" }, - { name: "minAmount", type: "uint256", internalType: "uint256" }, - { name: "maxAmount", type: "uint256", internalType: "uint256" }, - { name: "minPrice", type: "uint64", internalType: "uint64" }, - { name: "maxPrice", type: "uint64", internalType: "uint64" }, - { name: "opensAt", type: "uint64", internalType: "uint64" }, - { name: "closesAt", type: "uint64", internalType: "uint64" }, - { name: "payload", type: "bytes", internalType: "bytes" }, - ], - }, - { name: "purchasePermitSignature", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "renounceRole", - inputs: [ - { name: "role", type: "bytes32", internalType: "bytes32" }, - { name: "callerConfirmation", type: "address", internalType: "address" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "reset", - inputs: [{ name: "entityID", type: "bytes16", internalType: "bytes16" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "revokeRole", - inputs: [ - { name: "role", type: "bytes32", internalType: "bytes32" }, - { name: "account", type: "address", internalType: "address" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "saleUUID", - inputs: [], - outputs: [{ name: "", type: "bytes16", internalType: "bytes16" }], - stateMutability: "view", - }, - { - type: "function", - name: "supportsInterface", - inputs: [{ name: "interfaceId", type: "bytes4", internalType: "bytes4" }], - outputs: [{ name: "", type: "bool", internalType: "bool" }], - stateMutability: "view", - }, - { - type: "event", - name: "EntityReset", - inputs: [{ name: "entityID", type: "bytes16", indexed: true, internalType: "bytes16" }], - anonymous: false, - }, - { - type: "event", - name: "Purchased", - inputs: [ - { name: "addr", type: "address", indexed: true, internalType: "address" }, - { name: "entityID", type: "bytes16", indexed: true, internalType: "bytes16" }, - { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }, - { name: "totalAmount", type: "uint256", indexed: false, internalType: "uint256" }, - ], - anonymous: false, - }, - { - type: "event", - name: "RoleAdminChanged", - inputs: [ - { name: "role", type: "bytes32", indexed: true, internalType: "bytes32" }, - { name: "previousAdminRole", type: "bytes32", indexed: true, internalType: "bytes32" }, - { name: "newAdminRole", type: "bytes32", indexed: true, internalType: "bytes32" }, - ], - anonymous: false, - }, - { - type: "event", - name: "RoleGranted", - inputs: [ - { name: "role", type: "bytes32", indexed: true, internalType: "bytes32" }, - { name: "account", type: "address", indexed: true, internalType: "address" }, - { name: "sender", type: "address", indexed: true, internalType: "address" }, - ], - anonymous: false, - }, - { - type: "event", - name: "RoleRevoked", - inputs: [ - { name: "role", type: "bytes32", indexed: true, internalType: "bytes32" }, - { name: "account", type: "address", indexed: true, internalType: "address" }, - { name: "sender", type: "address", indexed: true, internalType: "address" }, - ], - anonymous: false, - }, - { type: "error", name: "AccessControlBadConfirmation", inputs: [] }, - { - type: "error", - name: "AccessControlUnauthorizedAccount", - inputs: [ - { name: "account", type: "address", internalType: "address" }, - { name: "neededRole", type: "bytes32", internalType: "bytes32" }, - ], - }, - { - type: "error", - name: "AddressTiedToAnotherEntity", - inputs: [ - { name: "addr", type: "address", internalType: "address" }, - { name: "got", type: "bytes16", internalType: "bytes16" }, - { name: "existing", type: "bytes16", internalType: "bytes16" }, - ], - }, - { - type: "error", - name: "AmountBelowMinimum", - inputs: [ - { name: "amount", type: "uint256", internalType: "uint256" }, - { name: "minAmount", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "AmountExceedsMaximum", - inputs: [ - { name: "amount", type: "uint256", internalType: "uint256" }, - { name: "maxAmount", type: "uint256", internalType: "uint256" }, - ], - }, - { type: "error", name: "ECDSAInvalidSignature", inputs: [] }, - { - type: "error", - name: "ECDSAInvalidSignatureLength", - inputs: [{ name: "length", type: "uint256", internalType: "uint256" }], - }, - { - type: "error", - name: "ECDSAInvalidSignatureS", - inputs: [{ name: "s", type: "bytes32", internalType: "bytes32" }], - }, - { - type: "error", - name: "PurchaseOutsideAllowedWindow", - inputs: [ - { name: "opensAt", type: "uint64", internalType: "uint64" }, - { name: "closesAt", type: "uint64", internalType: "uint64" }, - { name: "currentTime", type: "uint256", internalType: "uint256" }, - ], - }, - { type: "error", name: "PurchasePermitExpired", inputs: [] }, - { - type: "error", - name: "PurchasePermitSaleUUIDMismatch", - inputs: [ - { name: "got", type: "bytes16", internalType: "bytes16" }, - { name: "want", type: "bytes16", internalType: "bytes16" }, - ], - }, - { - type: "error", - name: "PurchasePermitSenderMismatch", - inputs: [ - { name: "got", type: "address", internalType: "address" }, - { name: "want", type: "address", internalType: "address" }, - ], - }, - { - type: "error", - name: "PurchasePermitUnauthorizedSigner", - inputs: [{ name: "signer", type: "address", internalType: "address" }], - }, - { - type: "error", - name: "TooManyAddressesForEntity", - inputs: [ - { name: "entityID", type: "bytes16", internalType: "bytes16" }, - { name: "max", type: "uint256", internalType: "uint256" }, - ], - }, - { type: "error", name: "ZeroAddress", inputs: [] }, - { type: "error", name: "ZeroEntityID", inputs: [] }, -] as const; diff --git a/src/Provider.tsx b/src/Provider.tsx index 482e649..0b390fa 100644 --- a/src/Provider.tsx +++ b/src/Provider.tsx @@ -3,13 +3,13 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConnectKitProvider, getDefaultConfig } from "connectkit"; import { SonarProvider } from "@echoxyz/sonar-react"; import { sonarConfig } from "./config"; -import { sepolia } from "wagmi/chains"; +import { baseSepolia } from "wagmi/chains"; const config = createConfig( getDefaultConfig({ - chains: [sepolia], + chains: [baseSepolia], transports: { - [sepolia.id]: http(), + [baseSepolia.id]: http(), }, // Required API Keys @@ -35,4 +35,3 @@ export function Provider({ children }: { children: React.ReactNode }) { ); } - diff --git a/src/abi/ERC20.ts b/src/abi/ERC20.ts new file mode 100644 index 0000000..2def6f5 --- /dev/null +++ b/src/abi/ERC20.ts @@ -0,0 +1,222 @@ +export const ERC20Abi = [ + { + constant: true, + inputs: [], + name: "name", + outputs: [ + { + name: "", + type: "string", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_from", + type: "address", + }, + { + name: "_to", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [], + name: "decimals", + outputs: [ + { + name: "", + type: "uint8", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: true, + inputs: [], + name: "symbol", + outputs: [ + { + name: "", + type: "string", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address", + }, + { + name: "_spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + name: "", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + payable: true, + stateMutability: "payable", + type: "fallback", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "owner", + type: "address", + }, + { + indexed: true, + name: "spender", + type: "address", + }, + { + indexed: false, + name: "value", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "from", + type: "address", + }, + { + indexed: true, + name: "to", + type: "address", + }, + { + indexed: false, + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, +]; diff --git a/src/abi/SettlementSale.ts b/src/abi/SettlementSale.ts new file mode 100644 index 0000000..42ec36c --- /dev/null +++ b/src/abi/SettlementSale.ts @@ -0,0 +1,2861 @@ +export const settlementSaleAbi = [ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PURCHASE_PERMIT_SIGNER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "REFUNDER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SALE_MANAGER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SETTLEMENT_FINALIZER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SETTLER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "TOKEN_RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "cancelBid", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRefund", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRefundEnabled", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "closeCommitment", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "entitiesIn", + "inputs": [ + { + "name": "from", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "to", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes16[]", + "internalType": "bytes16[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "entityAt", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes16", + "internalType": "bytes16" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "entityStateByID", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct SettlementSale.EntityStateView", + "components": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "bidTimestamp", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "cancelled", + "type": "bool", + "internalType": "bool" + }, + { + "name": "refunded", + "type": "bool", + "internalType": "bool" + }, + { + "name": "currentBid", + "type": "tuple", + "internalType": "struct SettlementSale.Bid", + "components": [ + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "walletStates", + "type": "tuple[]", + "internalType": "struct SettlementSale.WalletStateView[]", + "components": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "committedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "entityStatesByIDs", + "inputs": [ + { + "name": "entityIDs", + "type": "bytes16[]", + "internalType": "bytes16[]" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct SettlementSale.EntityStateView[]", + "components": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "bidTimestamp", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "cancelled", + "type": "bool", + "internalType": "bool" + }, + { + "name": "refunded", + "type": "bool", + "internalType": "bool" + }, + { + "name": "currentBid", + "type": "tuple", + "internalType": "struct SettlementSale.Bid", + "components": [ + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "walletStates", + "type": "tuple[]", + "internalType": "struct SettlementSale.WalletStateView[]", + "components": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "committedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "entityStatesIn", + "inputs": [ + { + "name": "from", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "to", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct SettlementSale.EntityStateView[]", + "components": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "bidTimestamp", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "cancelled", + "type": "bool", + "internalType": "bool" + }, + { + "name": "refunded", + "type": "bool", + "internalType": "bool" + }, + { + "name": "currentBid", + "type": "tuple", + "internalType": "struct SettlementSale.Bid", + "components": [ + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "walletStates", + "type": "tuple[]", + "internalType": "struct SettlementSale.WalletStateView[]", + "components": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "committedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "finalizeSettlement", + "inputs": [ + { + "name": "expectedTotalAcceptedAmount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "init", + "type": "tuple", + "internalType": "struct SettlementSale.Init", + "components": [ + { + "name": "saleUUID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "extraManagers", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "extraPausers", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "extraSettler", + "type": "address", + "internalType": "address" + }, + { + "name": "extraRefunder", + "type": "address", + "internalType": "address" + }, + { + "name": "purchasePermitSigner", + "type": "address", + "internalType": "address" + }, + { + "name": "proceedsReceiver", + "type": "address", + "internalType": "address" + }, + { + "name": "claimRefundEnabled", + "type": "bool", + "internalType": "bool" + }, + { + "name": "maxWalletsPerEntity", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "paymentTokens", + "type": "address[]", + "internalType": "contract IERC20Metadata[]" + }, + { + "name": "expectedPaymentTokenDecimals", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "maxWalletsPerEntity", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "uint8" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "numCommitments", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "numEntities", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "numEntityAllocations", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "openCancellation", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "openCommitment", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "openSettlement", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pause", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "paused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "paymentTokens", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address[]", + "internalType": "contract IERC20[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proceedsReceiver", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "processRefunds", + "inputs": [ + { + "name": "entityIDs", + "type": "bytes16[]", + "internalType": "bytes16[]" + }, + { + "name": "skipAlreadyRefunded", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "readCommitmentDataAt", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct ICommitmentDataReader.CommitmentData", + "components": [ + { + "name": "commitmentID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "saleSpecificEntityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "timestamp", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "refunded", + "type": "bool", + "internalType": "bool" + }, + { + "name": "amounts", + "type": "tuple[]", + "internalType": "struct WalletTokenAmount[]", + "components": [ + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "extraData", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "readCommitmentDataIn", + "inputs": [ + { + "name": "from", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "to", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct ICommitmentDataReader.CommitmentData[]", + "components": [ + { + "name": "commitmentID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "saleSpecificEntityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "timestamp", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "refunded", + "type": "bool", + "internalType": "bool" + }, + { + "name": "amounts", + "type": "tuple[]", + "internalType": "struct WalletTokenAmount[]", + "components": [ + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "extraData", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "readEntityAllocationDataAt", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IEntityAllocationDataReader.EntityAllocationData", + "components": [ + { + "name": "saleSpecificEntityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmounts", + "type": "tuple[]", + "internalType": "struct WalletTokenAmount[]", + "components": [ + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "readEntityAllocationDataIn", + "inputs": [ + { + "name": "from", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "to", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct IEntityAllocationDataReader.EntityAllocationData[]", + "components": [ + { + "name": "saleSpecificEntityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmounts", + "type": "tuple[]", + "internalType": "struct WalletTokenAmount[]", + "components": [ + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "recoverTokens", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "contract IERC20" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "replaceBidWithApproval", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "contract IERC20" + }, + { + "name": "bid", + "type": "tuple", + "internalType": "struct SettlementSale.Bid", + "components": [ + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "purchasePermit", + "type": "tuple", + "internalType": "struct PurchasePermitV3", + "components": [ + { + "name": "saleSpecificEntityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "saleUUID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "expiresAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "minAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "minPrice", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "maxPrice", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "opensAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "closesAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "payload", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "purchasePermitSignature", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "replaceBidWithPermit", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "contract IERC20" + }, + { + "name": "bid", + "type": "tuple", + "internalType": "struct SettlementSale.Bid", + "components": [ + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "purchasePermit", + "type": "tuple", + "internalType": "struct PurchasePermitV3", + "components": [ + { + "name": "saleSpecificEntityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "saleUUID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "expiresAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "minAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "minPrice", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "maxPrice", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "opensAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "closesAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "payload", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "purchasePermitSignature", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "erc20PermitDeadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "erc20PermitSignature", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "saleUUID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes16", + "internalType": "bytes16" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setAllocations", + "inputs": [ + { + "name": "allocations", + "type": "tuple[]", + "internalType": "struct IOffchainSettlement.Allocation[]", + "components": [ + { + "name": "saleSpecificEntityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "acceptedAmount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "allowOverwrite", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setClaimRefundEnabled", + "inputs": [ + { + "name": "enabled", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setMaxWalletsPerEntity", + "inputs": [ + { + "name": "max", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setPaused", + "inputs": [ + { + "name": "isPaused", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setProceedsReceiver", + "inputs": [ + { + "name": "newProceedsReceiver", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "stage", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "enum SettlementSale.Stage" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalAcceptedAmount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalAcceptedAmountByToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalCommittedAmount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalCommittedAmountByToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalRefundedAmount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalRefundedAmountByToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "unsafeSetStage", + "inputs": [ + { + "name": "newStage", + "type": "uint8", + "internalType": "enum SettlementSale.Stage" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "walletStateByAddress", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct SettlementSale.WalletStateView", + "components": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "committedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "walletStatesByAddresses", + "inputs": [ + { + "name": "addrs", + "type": "address[]", + "internalType": "address[]" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct SettlementSale.WalletStateView[]", + "components": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "committedAmountByToken", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "withdraw", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "withdrawPartial", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "contract IERC20" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "withdrawnAmount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "withdrawnAmountByToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct TokenAmount[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "AllocationSet", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "acceptedAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BidCancelled", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BidPlaced", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "bid", + "type": "tuple", + "indexed": false, + "internalType": "struct SettlementSale.Bid", + "components": [ + { + "name": "lockup", + "type": "bool", + "internalType": "bool" + }, + { + "name": "price", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ClaimRefundEnabledChanged", + "inputs": [ + { + "name": "enabled", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EntityInitialized", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EntityRefunded", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MaxWalletsPerEntityChanged", + "inputs": [ + { + "name": "previousMax", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + }, + { + "name": "newMax", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PausedStateChanged", + "inputs": [ + { + "name": "paused", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ProceedsReceiverChanged", + "inputs": [ + { + "name": "previousReceiver", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newReceiver", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ProceedsWithdrawn", + "inputs": [ + { + "name": "receiver", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RefundedEntitySkipped", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StageChanged", + "inputs": [ + { + "name": "previousStage", + "type": "uint8", + "indexed": true, + "internalType": "enum SettlementSale.Stage" + }, + { + "name": "newStage", + "type": "uint8", + "indexed": true, + "internalType": "enum SettlementSale.Stage" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TokensRecovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WalletInitialized", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WalletRefunded", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "indexed": true, + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "AddressInsufficientBalance", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "AllocationAlreadySet", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "acceptedAmount", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "AllocationExceedsCommitment", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "allocation", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "commitment", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "AlreadyRefunded", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + } + ] + }, + { + "type": "error", + "name": "BidAlreadyCancelled", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + } + ] + }, + { + "type": "error", + "name": "BidAmountCannotBeLowered", + "inputs": [ + { + "name": "got", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "want", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "BidBelowMinAmount", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "min", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "BidExceedsMaxAmount", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "max", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "BidLockupCannotBeUndone", + "inputs": [] + }, + { + "type": "error", + "name": "BidMustHaveLockup", + "inputs": [] + }, + { + "type": "error", + "name": "BidOutsideAllowedWindow", + "inputs": [ + { + "name": "opensAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "closesAt", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "currentTime", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "BidPriceBelowMinPrice", + "inputs": [ + { + "name": "price", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "min", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "BidPriceCannotBeLowered", + "inputs": [ + { + "name": "got", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "want", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "BidPriceExceedsMaxPrice", + "inputs": [ + { + "name": "price", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "max", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ClaimRefundDisabled", + "inputs": [] + }, + { + "type": "error", + "name": "DuplicatePaymentToken", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ECDSAInvalidSignature", + "inputs": [] + }, + { + "type": "error", + "name": "ECDSAInvalidSignatureLength", + "inputs": [ + { + "name": "length", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ECDSAInvalidSignatureS", + "inputs": [ + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "EntityNotInitialized", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + } + ] + }, + { + "type": "error", + "name": "FailedInnerCall", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidPaymentToken", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "InvalidPaymentTokenDecimals", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "got", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "want", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidSaleUUID", + "inputs": [ + { + "name": "got", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "want", + "type": "bytes16", + "internalType": "bytes16" + } + ] + }, + { + "type": "error", + "name": "InvalidSender", + "inputs": [ + { + "name": "got", + "type": "address", + "internalType": "address" + }, + { + "name": "want", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "InvalidStage", + "inputs": [ + { + "name": "got", + "type": "uint8", + "internalType": "enum SettlementSale.Stage" + }, + { + "name": "want", + "type": "uint8[]", + "internalType": "enum SettlementSale.Stage[]" + } + ] + }, + { + "type": "error", + "name": "MaxWalletsPerEntityExceeded", + "inputs": [ + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "count", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "max", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "NoPaymentTokens", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "PurchasePermitExpired", + "inputs": [ + { + "name": "expiresAt", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "currentTime", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "SalePaused", + "inputs": [] + }, + { + "type": "error", + "name": "UnauthorizedSigner", + "inputs": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "UnexpectedTotalAcceptedAmount", + "inputs": [ + { + "name": "got", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "want", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "WalletNotAssociatedWithEntity", + "inputs": [ + { + "name": "wallet", + "type": "address", + "internalType": "address" + }, + { + "name": "entityID", + "type": "bytes16", + "internalType": "bytes16" + } + ] + }, + { + "type": "error", + "name": "WalletNotInitialized", + "inputs": [ + { + "name": "wallet", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "WalletTiedToAnotherEntity", + "inputs": [ + { + "name": "got", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "want", + "type": "bytes16", + "internalType": "bytes16" + }, + { + "name": "wallet", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "WithdrawalExceedsAvailable", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "requested", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "available", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ZeroAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAmount", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroEntityID", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroMaxWalletsPerEntity", + "inputs": [] + } +] as const; diff --git a/src/components/sale/PurchaseCard.tsx b/src/components/sale/CommitCard.tsx similarity index 66% rename from src/components/sale/PurchaseCard.tsx rename to src/components/sale/CommitCard.tsx index ee370e6..980fee3 100644 --- a/src/components/sale/PurchaseCard.tsx +++ b/src/components/sale/CommitCard.tsx @@ -1,6 +1,6 @@ -import { PrePurchaseFailureReason, GeneratePurchasePermitResponse, EntityID } from "@echoxyz/sonar-core"; +import { PrePurchaseFailureReason, GeneratePurchasePermitResponse, EntityID, Hex } from "@echoxyz/sonar-core"; import { useState } from "react"; -import { saleUUID } from "../../config"; +import { paymentTokenAddress, saleUUID } from "../../config"; import { useSonarPurchase, UseSonarPurchaseResultNotReadyToPurchase, @@ -30,12 +30,12 @@ function readinessConfig( }); if (sonarPurchaser.readyToPurchase) { - return okConfig("You are ready to purchase"); + return okConfig("You are ready to commit funds"); } switch (sonarPurchaser.failureReason) { case PrePurchaseFailureReason.REQUIRES_LIVENESS: - return okConfig("Complete a liveness check in order to purchase."); + return okConfig("Complete a liveness check in order to commit funds."); case PrePurchaseFailureReason.WALLET_RISK: return warningConfig("The connected wallet is not eligible for this sale. Connect a different wallet."); case PrePurchaseFailureReason.MAX_WALLETS_USED: @@ -53,34 +53,30 @@ function readinessConfig( } } -function ReadyToPurchaseSection({ - walletAddress, +function CommitSection({ + saleSpecificEntityID, generatePurchasePermit, }: { - walletAddress: `0x${string}`; + saleSpecificEntityID: Hex; generatePurchasePermit: () => Promise; }) { - const { - commitWithPermit, - amountInContract, - amountInContractError, - awaitingTxReceipt, - txReceipt, - awaitingTxReceiptError, - } = useSaleContract(walletAddress); + const { commitWithPermit, entityState, entityStateError, awaitingTxReceipt, txReceipt, awaitingTxReceiptError } = + useSaleContract(saleSpecificEntityID); const [loading, setLoading] = useState(false); const [error, setError] = useState(undefined); + const [humanReadableAmount, setHumanReadableAmount] = useState("1"); const purchase = async () => { setLoading(true); setError(undefined); try { const purchasePermitResp = await generatePurchasePermit(); + const amount = BigInt(Math.floor(parseFloat(humanReadableAmount) * 1e6)); await commitWithPermit({ purchasePermitResp: purchasePermitResp, - // TODO: could support selecting the amount - amount: BigInt(1e8), + token: paymentTokenAddress, + amount, }); } catch (error) { setError(error as Error); @@ -89,32 +85,50 @@ function ReadyToPurchaseSection({ } }; + // Get the committed amount for the payment token + const committedAmount = entityState?.currentBid?.amount; + // TODO: could fetch and show the user their allocation return (
+
+ + setHumanReadableAmount(e.target.value)} + disabled={loading || awaitingTxReceipt} + className="px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-gray-900" + placeholder="Enter amount" + /> +
{awaitingTxReceipt && !txReceipt &&

Waiting for transaction receipt...

} - {txReceipt?.status === "success" &&

Purchase successful

} - {txReceipt?.status === "reverted" &&

Purchase reverted

} + {txReceipt?.status === "success" &&

Commitment successful

} + {txReceipt?.status === "reverted" &&

Commitment reverted

} {error &&

{error.message}

} {awaitingTxReceiptError &&

{awaitingTxReceiptError.message}

}
- {amountInContractError ? ( -

{amountInContractError.message}

+ {entityStateError ? ( +

{entityStateError.message}

) : (

- Current amount in contract:{" "} - {amountInContract !== undefined ? `${Number(amountInContract) / 1e6}` : "Loading..."} + Current committed amount:{" "} + {committedAmount !== undefined ? `${Number(committedAmount) / 1e6} USDC` : "Loading..."}

)}
@@ -122,7 +136,15 @@ function ReadyToPurchaseSection({ ); } -function PurchaseCard({ entityID, walletAddress }: { entityID: EntityID; walletAddress: `0x${string}` }) { +function CommitCard({ + entityID, + saleSpecificEntityID, + walletAddress, +}: { + entityID: EntityID; + saleSpecificEntityID: Hex; + walletAddress: `0x${string}`; +}) { const sonarPurchaser = useSonarPurchase({ saleUUID, entityID, @@ -146,8 +168,8 @@ function PurchaseCard({ entityID, walletAddress }: { entityID: EntityID; walletA
{sonarPurchaser.readyToPurchase && ( - )} @@ -167,4 +189,4 @@ function PurchaseCard({ entityID, walletAddress }: { entityID: EntityID; walletA ); } -export default PurchaseCard; +export default CommitCard; diff --git a/src/config.ts b/src/config.ts index 1af1688..bd81968 100644 --- a/src/config.ts +++ b/src/config.ts @@ -11,5 +11,6 @@ export const sonarConfig = { export const saleUUID = import.meta.env.VITE_SALE_UUID ?? ""; export const saleContract = (import.meta.env.VITE_SALE_CONTRACT_ADDRESS as Hex) ?? "0x0000000000000000000000000000000000000000"; +export const paymentTokenAddress = + (import.meta.env.VITE_PAYMENT_TOKEN_ADDRESS as Hex) ?? "0x0000000000000000000000000000000000000000"; export const sonarHomeURL = new URL(`/sonar/${saleUUID}/home`, sonarConfig.frontendURL); - diff --git a/src/hooks.ts b/src/hooks.ts index 00d9ea2..eb13802 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -1,12 +1,13 @@ -import { BasicPermitV3, GeneratePurchasePermitResponse } from "@echoxyz/sonar-core"; -import { useCallback, useEffect, useState } from "react"; +import { BasicPermitV3, GeneratePurchasePermitResponse, Hex } from "@echoxyz/sonar-core"; +import { useCallback, useState } from "react"; import { useReadContract, useWriteContract, useWaitForTransactionReceipt } from "wagmi"; import { saleContract } from "./config"; -import { examplSaleABI } from "./ExampleSaleABI"; +import { settlementSaleAbi } from "./abi/SettlementSale"; +import { ERC20Abi } from "./abi/ERC20"; import { useConfig } from "wagmi"; -import { simulateContract } from "wagmi/actions"; +import { waitForTransactionReceipt, simulateContract } from "wagmi/actions"; -export const useSaleContract = (walletAddress: `0x${string}`) => { +export const useSaleContract = (saleSpecificEntityID: Hex) => { const { writeContractAsync } = useWriteContract(); const config = useConfig(); @@ -21,66 +22,77 @@ export const useSaleContract = (walletAddress: `0x${string}`) => { }); const commitWithPermit = useCallback( - async ({ purchasePermitResp, amount }: { purchasePermitResp: GeneratePurchasePermitResponse; amount: bigint }) => { + async ({ + purchasePermitResp, + token, + amount, + }: { + purchasePermitResp: GeneratePurchasePermitResponse; + token: `0x${string}`; + amount: bigint; + }) => { if (!("OpensAt" in purchasePermitResp.PermitJSON)) { throw new Error("Invalid purchase permit response"); } const permit = purchasePermitResp.PermitJSON as BasicPermitV3; - const { request } = await simulateContract(config, { + const { request: approveRequest } = await simulateContract(config, { + address: token, + abi: ERC20Abi, + functionName: "approve", + args: [saleContract, amount], + }); + + const approveHash = await writeContractAsync(approveRequest); + await waitForTransactionReceipt(config, { hash: approveHash }); + + const bidArgs = [ + token, + { lockup: false, price: 0n, amount: amount }, + { + saleSpecificEntityID: permit.SaleSpecificEntityID, + saleUUID: permit.SaleUUID, + wallet: permit.Wallet, + expiresAt: BigInt(permit.ExpiresAt), + minAmount: BigInt(permit.MinAmount), + maxAmount: BigInt(permit.MaxAmount), + minPrice: BigInt(permit.MinPrice), + maxPrice: BigInt(permit.MaxPrice), + opensAt: BigInt(permit.OpensAt), + closesAt: BigInt(permit.ClosesAt), + payload: permit.Payload, + }, + purchasePermitResp.Signature, + ] as const; + + // TODO could also show an example of using the replaceBidWithPermit function instead of the replaceBidWithApproval function + const { request: bidRequest } = await simulateContract(config, { address: saleContract, - abi: examplSaleABI, - functionName: "purchase", - args: [ - amount, - { - saleSpecificEntityID: permit.SaleSpecificEntityID, - saleUUID: permit.SaleUUID, - wallet: permit.Wallet, - expiresAt: BigInt(permit.ExpiresAt), - minAmount: BigInt(permit.MinAmount), - maxAmount: BigInt(permit.MaxAmount), - minPrice: BigInt(permit.MinPrice), - maxPrice: BigInt(permit.MaxPrice), - opensAt: BigInt(permit.OpensAt), - closesAt: BigInt(permit.ClosesAt), - payload: permit.Payload, - }, - purchasePermitResp.Signature, - ] as const, + abi: settlementSaleAbi, + functionName: "replaceBidWithApproval", + args: bidArgs, }); - setTxHash( - await writeContractAsync(request, { - onError: (error: Error) => { - throw error; - }, - }) - ); + const bidHash = await writeContractAsync(bidRequest); + + setTxHash(bidHash); }, [writeContractAsync, config] ); - const { - data: amountInContract, - refetch: refetchAmountInContract, - error: amountInContractError, - } = useReadContract({ + const { data: entityState, error: entityStateError } = useReadContract({ address: saleContract, - abi: examplSaleABI, - functionName: "amountByAddress", - args: [walletAddress], + abi: settlementSaleAbi, + functionName: "entityStateByID", + args: [saleSpecificEntityID], + query: { + refetchInterval: 3000, + }, }); - useEffect(() => { - if (txReceipt?.status === "success") { - refetchAmountInContract(); - } - }, [txReceipt?.status, refetchAmountInContract]); - return { - amountInContract, - amountInContractError, + entityState, + entityStateError, commitWithPermit, awaitingTxReceipt, txReceipt, diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 0a35115..99530fc 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -3,7 +3,7 @@ import { ConnectKitButton } from "connectkit"; import { useSonarAuth, useSonarEntity, useSonarEntities } from "@echoxyz/sonar-react"; import { saleUUID, sonarHomeURL, sonarConfig } from "../config"; import { useAccount } from "wagmi"; -import PurchaseCard from "../components/sale/PurchaseCard"; +import CommitCard from "../components/sale/CommitCard"; import { SaleEligibility } from "@echoxyz/sonar-core"; import { AuthenticationSection } from "../components/auth/AuthenticationSection"; import { EntityCard } from "../components/entity/EntityCard"; @@ -214,11 +214,11 @@ export function Home() { - {/* Purchase Panel */} + {/* Commit Panel */} {isEligible && address && (
-

Make a Purchase

- +

Commit funds

+
)}