Skip to content

Commit

Permalink
allow 1155 transfers using transferNFT to set amount, add 1155 tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bjfresh committed Oct 12, 2023
1 parent a6f9cd7 commit e0b5ea5
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 80 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-steaks-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tokenbound/sdk': patch
---

allow 1155 transfers using transferNFT to set amount, add 1155 tests
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tokenbound/sdk",
"version": "0.3.11",
"version": "0.3.12",
"type": "module",
"files": [
"dist"
Expand Down
25 changes: 10 additions & 15 deletions packages/sdk/src/TokenboundClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ class TokenboundClient {
* @param {string} params.tokenContract The address of the token contract
* @param {string} params.tokenId The token ID
* @param {string} params.recipientAddress The address to which the token should be transferred
* @param {string} params.amount The amount of tokens to transfer, (eg. 1 NFT = 1)
* @returns a Promise that resolves to the transaction hash of the executed call
*/
public async transferNFT(params: NFTTransferParams): Promise<`0x${string}`> {
Expand All @@ -391,30 +392,24 @@ class TokenboundClient {
tokenType,
tokenContract,
tokenId,
amount = 1,
recipientAddress,
} = params

const is1155: boolean = tokenType === NFTTokenType.ERC1155

if (!is1155 && amount !== 1) {
throw new Error('ERC721 transfers can only transfer one token at a time.')
}

try {
const recipient = await resolvePossibleENS(this.publicClient, recipientAddress)

// Configure required args based on token type
const transferArgs: unknown[] = is1155
? [
// ERC1155: safeTransferFrom(address,address,uint256,uint256,bytes)
tbAccountAddress,
recipient,
tokenId,
1,
'0x',
]
: [
// ERC721: safeTransferFrom(address,address,uint256)
tbAccountAddress,
recipient,
tokenId,
]
// ERC1155: safeTransferFrom(address,address,uint256,uint256,bytes)
// ERC721: safeTransferFrom(address,address,uint256)
const sharedArgs = [tbAccountAddress, recipient, tokenId]
const transferArgs: unknown[] = is1155 ? [...sharedArgs, amount, '0x'] : sharedArgs

const transferCallData = encodeFunctionData({
abi: is1155 ? erc1155Abi : erc721Abi,
Expand Down
148 changes: 87 additions & 61 deletions packages/sdk/src/test/TestAll.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// This test suite is for testing the SDK methods with
// viem walletClient + publicClient and with Ethers 5/6.
// This test suite is for testing SDK methods with
// viem walletClient + publicClient and Ethers 5/6.

import { zora } from 'viem/chains'
import { describe, expect, it, vi } from 'vitest'
import { describe, beforeAll, afterAll, test, expect, it, vi } from 'vitest'
import { providers } from 'ethers'
import { waitFor } from './mockWallet'
import { createAnvil } from '@viem/anvil'
Expand All @@ -17,8 +17,8 @@ import {
parseUnits,
formatEther,
getContract,
// encodeAbiParameters,
// parseAbiParameters,
encodeAbiParameters,
parseAbiParameters,
} from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { CreateAccountParams, TokenboundClient } from '@tokenbound/sdk'
Expand All @@ -38,20 +38,11 @@ import {
getPublicClient,
getWETHBalance,
// debugTransaction,
// getZora1155Balance,
getZora1155Balance,
getZora721Balance,
} from './utils'
import {
ANVIL_CONFIG,
CREATE_ANVIL_OPTIONS,
zora721,
// zora1155
} from './config'
import {
wethABI,
// zora1155ABI
} from './wagmi-cli-hooks/generated'
import { getEnsAddress } from 'viem/ens'
import { ANVIL_CONFIG, CREATE_ANVIL_OPTIONS, zora721, zora1155 } from './config'
import { wethABI } from './wagmi-cli-hooks/generated'

const TIMEOUT = 60000 // default 10000
const ANVIL_USER_0 = getAddress(ANVIL_ACCOUNTS[0].address)
Expand Down Expand Up @@ -461,7 +452,22 @@ function runTxTests({
})
})

it('can transferNFT with the TBA', async () => {
it('will not allow transferNFT 721 with an amount other than 1', async () => {
vi.spyOn(console, 'error')

await expect(() =>
tokenboundClient.transferNFT({
account: ZORA721_TBA_ADDRESS,
tokenType: 'ERC721',
tokenContract: zora721.proxyContractAddress,
tokenId: TOKENID1_IN_TBA,
recipientAddress: ANVIL_USER_1,
amount: 2,
})
).rejects.toThrowError()
})

it('can transferNFT a 721 with the TBA', async () => {
const transferNFTHash = await tokenboundClient.transferNFT({
account: ZORA721_TBA_ADDRESS,
tokenType: 'ERC721',
Expand Down Expand Up @@ -531,46 +537,69 @@ function runTxTests({
})
})

// it('can mint an 1155 with the TBA', async () => {
// const mintingAccount: `0x${string}` = ZORA721_TBA_ADDRESS
// // const mintAddress: `0x${string}` = ANVIL_USER_0

// const minterArguments: `0x${string}` = encodeAbiParameters(
// parseAbiParameters('address'),
// [mintingAccount]
// )

// const mint1155TxHash = await tokenboundClient.executeCall({
// account: mintingAccount,
// to: zora1155.proxyContractAddress,
// value: zora1155.mintFee * zora1155.quantity,
// data: encodeFunctionData({
// abi: zora1155ABI,
// functionName: 'mint',
// args: [
// zora1155.fixedPriceSalesStrategy,
// zora1155.tokenId,
// zora1155.quantity,
// minterArguments,
// ],
// }),
// })

// await debugTransaction({ publicClient, hash: mint1155TxHash })

// const zora1155BalanceInTBA = await getZora1155Balance({
// publicClient,
// walletAddress: mintingAccount,
// })

// console.log('1155 Balance', zora1155BalanceInTBA)

// await waitFor(() => {
// expect(mint1155TxHash).toMatch(ADDRESS_REGEX)
// expect(zora1155BalanceInTBA).toBe(5n)
// expect(true).toBe(true)
// })
// })
it('can mint an 1155 with the TBA', async () => {
const mintingAccount: `0x${string}` = ZORA721_TBA_ADDRESS

const minterArguments: `0x${string}` = encodeAbiParameters(
parseAbiParameters('address'),
[mintingAccount]
)

const data = encodeFunctionData({
abi: zora1155.abi,
functionName: 'mint',
args: [
zora1155.fixedPriceSalesStrategy, // IMinter1155
zora1155.tokenId, // uint256
zora1155.quantity, // uint256
minterArguments, // bytes
],
})

const mint1155TxHash = await tokenboundClient.executeCall({
account: mintingAccount,
to: zora1155.proxyContractAddress,
value: zora1155.mintFee * zora1155.quantity,
data,
})

const zora1155BalanceInTBA = await getZora1155Balance({
publicClient,
walletAddress: mintingAccount,
})

console.log('1155 Balance', zora1155BalanceInTBA)

await waitFor(() => {
expect(mint1155TxHash).toMatch(ADDRESS_REGEX)
expect(zora1155BalanceInTBA).toBe(5n)
})
})

it('can transferNFT an 1155 with the TBA', async () => {
const transferAmount = 2

const transferNFTHash = await tokenboundClient.transferNFT({
account: ZORA721_TBA_ADDRESS,
tokenType: 'ERC1155',
tokenContract: zora1155.proxyContractAddress,
tokenId: zora1155.tokenId.toString(),
recipientAddress: ANVIL_USER_1,
amount: transferAmount,
})

const anvilAccount1_1155Balance = await getZora1155Balance({
publicClient,
walletAddress: ANVIL_USER_1,
})

console.log('1155 Balance', anvilAccount1_1155Balance)

await waitFor(() => {
expect(transferNFTHash).toMatch(ADDRESS_REGEX)
expect(anvilAccount1_1155Balance).toBe(BigInt(transferAmount))
})
})

// Test signing in viem only.
// Ethers 5/6 don't appear to support signing messages via personal_sign with this testing configuration.
Expand Down Expand Up @@ -763,9 +792,6 @@ function runTxTests({
expect(ensWETHBalance).toBe(transferWeiValue)
})
})

test.todo('can transferNFT with an 1155', async () => {})
test.todo('can transfer with ENS', async () => {})
})
}

Expand Down
7 changes: 4 additions & 3 deletions packages/sdk/src/test/config/mints.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getAddress } from 'viem'
import { ethToWei } from '../utils'
import { zora721DropABI } from '../wagmi-cli-hooks/generated'
import { zora721DropABI, zora1155ABI } from '../wagmi-cli-hooks/generated'

// Zora Webb's First Deep Field: https://zora.co/collect/eth:0x28ee638f2fcb66b4106acab7efd225aeb2bd7e8d
export const zora721 = {
Expand All @@ -12,9 +12,10 @@ export const zora721 = {

// https://zora.co/collect/eth:0x373075bab7d668ed2473d8233ebdebcf49eb758e/1
export const zora1155 = {
fixedPriceSalesStrategy: getAddress('0x8A1DBE9b1CeB1d17f92Bebf10216FCFAb5C3fbA7'), // IMinter1155 minter contract from https://github.com/ourzora/zora-1155-contracts/blob/main/addresses/1.json
abi: zora1155ABI,
fixedPriceSalesStrategy: getAddress('0x5Ff5a77dD2214d863aCA809C0168941052d9b180'), // Zora IMinter1155 from https://etherscan.io/address/0x5Ff5a77dD2214d863aCA809C0168941052d9b180
proxyContractAddress: getAddress('0x373075bab7d668ed2473d8233ebdebcf49eb758e'), // proxied Zora 1155 contract
tokenId: BigInt(1),
mintFee: ethToWei(0.000777), // 0.000777 ETH
mintFee: ethToWei(0.000777),
quantity: BigInt(5),
}
1 change: 1 addition & 0 deletions packages/sdk/src/types/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export type NFTTransferParams = Prettify<
NFTParams & {
recipientAddress: PossibleENSAddress
account: `0x${string}`
amount?: number
}
>

Expand Down

0 comments on commit e0b5ea5

Please sign in to comment.