Skip to content

Commit

Permalink
Merge pull request #325 from rabbitholegg:mmackz/fabric-projectfees
Browse files Browse the repository at this point in the history
feat(fabric): add projectFees/simulation functions
  • Loading branch information
mmackz authored Apr 9, 2024
2 parents 9870bbb + 03fedae commit 193c13e
Show file tree
Hide file tree
Showing 7 changed files with 1,225 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-bobcats-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rabbitholegg/questdk-plugin-fabric": minor
---

add projectFees/simulation functions
61 changes: 59 additions & 2 deletions packages/fabric/src/Fabric.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { getFees, getMintIntent, mint, simulateMint } from './Fabric'
import { failingTestCases, passingTestCases } from './test-transactions'
import {
Chains,
type MintIntentParams,
} from '@rabbitholegg/questdk-plugin-utils'
import { apply } from '@rabbitholegg/questdk/filter'
import { type Address } from 'viem'
import { describe, expect, test } from 'vitest'
import { passingTestCases, failingTestCases } from './test-transactions'
import { mint } from './Fabric'

describe('Given the fabric plugin', () => {
describe('When handling the mint action', () => {
Expand Down Expand Up @@ -59,3 +64,55 @@ describe('Given the fabric plugin', () => {
})
})
})

describe('Given the getFee function', () => {
test('should return the correct project + action fee for a 721 mint', async () => {
const contractAddress: Address =
'0xd77269c83aab591ca834b3687e1f4164b2ff25f5'
const mintParams = { chainId: Chains.SEPOLIA, contractAddress, amount: 1n }
const fee = await getFees(mintParams)
expect(fee.projectFee).equals(0n)
expect(fee.actionFee).equals(499999999997664000n)
})
})

describe('Given the getMintIntent function', () => {
// Define the constant for the contract address
const CONTRACT_ADDRESS = '0x2efc6064239121d1d7efb503355daa82b87ee89c'
const RECIPIENT_ADDRESS = '0x1234567890123456789012345678901234567890'

test('returns a TransactionRequest with correct properties', async () => {
const mint: MintIntentParams = {
chainId: Chains.BASE,
contractAddress: CONTRACT_ADDRESS,
amount: BigInt('1'),
recipient: RECIPIENT_ADDRESS,
}

const result = await getMintIntent(mint)

expect(result).toEqual({
from: mint.recipient,
to: mint.contractAddress,
data: '0xa0712d6800000000000000000000000000000000000000000000000000028fbee4d84c00',
})
})
})

describe('simulateMint function', () => {
test('should simulate a mint', async () => {
const mint: MintIntentParams = {
chainId: Chains.SEPOLIA,
contractAddress: '0xD77269c83AAB591Ca834B3687E1f4164B2fF25f5',
amount: BigInt(2),
recipient: '0x000000000000000000000000000000000000dEaD',
}
const value = 999999999995328000n
const account = '0x000000000000000000000000000000000000dEaD'

const result = await simulateMint(mint, value, account)
const request = result.request
expect(request.address).toBe(mint.contractAddress)
expect(request.value).toBe(value)
})
})
111 changes: 107 additions & 4 deletions packages/fabric/src/Fabric.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { FABRIC_ABI } from './abi'
import { getContractData } from './utils'
import {
type TransactionFilter,
type MintActionParams,
type TransactionFilter,
compressJson,
} from '@rabbitholegg/questdk'
import { type Address } from 'viem'
import { Chains } from '@rabbitholegg/questdk-plugin-utils'
import { FABRIC_ABI } from './abi'
import {
Chains,
DEFAULT_ACCOUNT,
type MintIntentParams,
} from '@rabbitholegg/questdk-plugin-utils'
import {
type Address,
type PublicClient,
type SimulateContractReturnType,
type TransactionRequest,
encodeFunctionData,
zeroAddress,
} from 'viem'

export const mint = async (
mint: MintActionParams,
Expand All @@ -21,6 +33,97 @@ export const mint = async (
})
}

export const getProjectFees = async (
mint: MintActionParams,
): Promise<bigint> => {
const fees = await getFees(mint)
return fees.projectFee + fees.actionFee
}

export const getFees = async (
mint: MintActionParams,
): Promise<{ actionFee: bigint; projectFee: bigint }> => {
const { chainId, contractAddress, amount } = mint

const { erc20Address, minPurchaseSeconds, tps } = await getContractData(
chainId,
contractAddress,
)

if (erc20Address !== zeroAddress) {
throw new Error('ERC20 not supported')
}

const mintUnits = typeof amount === 'number' ? BigInt(amount) : BigInt(1)

const mintCost = (minPurchaseSeconds as bigint) * (tps as bigint) * mintUnits

return { actionFee: mintCost, projectFee: BigInt(0) }
}

export const getMintIntent = async (
mint: MintIntentParams,
): Promise<TransactionRequest> => {
const { chainId, amount, contractAddress, recipient } = mint

const { erc20Address, minPurchaseSeconds, tps } = await getContractData(
chainId,
contractAddress,
)

if (erc20Address !== zeroAddress) {
throw new Error('ERC20 not supported')
}

const mintArgs = [(minPurchaseSeconds as bigint) * (tps as bigint) * amount]

const data = encodeFunctionData({
abi: FABRIC_ABI,
functionName: 'mint',
args: mintArgs,
})

return {
from: recipient,
to: contractAddress,
data,
}
}

export const simulateMint = async (
mint: MintIntentParams,
value: bigint,
account?: Address,
client?: PublicClient,
): Promise<SimulateContractReturnType> => {
const { chainId, contractAddress, amount } = mint

const from = account ?? DEFAULT_ACCOUNT
const {
erc20Address,
minPurchaseSeconds,
tps,
client: _client,
} = await getContractData(chainId, contractAddress, client)

// fail simulation if erc20 is used
if (erc20Address !== zeroAddress) {
throw new Error('ERC20 not supported')
}

const mintArgs = [(minPurchaseSeconds as bigint) * (tps as bigint) * amount]

const result = await _client.simulateContract({
address: contractAddress,
value,
abi: FABRIC_ABI,
functionName: 'mint',
args: mintArgs,
account: from,
})
return result
}

export const getSupportedTokenAddresses = async (
_chainId: number,
): Promise<Address[]> => {
Expand Down
Loading

0 comments on commit 193c13e

Please sign in to comment.