[Multi] clean up examples & storage (#8)

This commit is contained in:
Jonas Daniels
2022-08-29 07:11:15 +00:00
committed by GitHub
parent 134f91eba8
commit 86e3b5861a
95 changed files with 650 additions and 73480 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/storage": patch
---
include additional file and buffer related helpers in storage package
+5
View File
@@ -0,0 +1,5 @@
---
"thirdweb": patch
---
remove examples
+8
View File
@@ -0,0 +1,8 @@
---
"@thirdweb-dev/auth": patch
"@thirdweb-dev/react": patch
"@thirdweb-dev/sdk": patch
"@thirdweb-dev/solana": patch
---
use storage helpers from @thirdweb-dev/storage
+3 -3
View File
@@ -1,4 +1,4 @@
{
"singleQuote": false,
"trailingComma": "all"
}
"singleQuote": false,
"trailingComma": "all"
}
+1
View File
@@ -13,6 +13,7 @@
},
"devDependencies": {
"@changesets/cli": "^2.24.3",
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
"eslint": "^8.23.0",
"eslint-config-acme": "*",
"prettier": "^2.7.1",
-9
View File
@@ -1,9 +0,0 @@
/node_modules
/dist
/express
/next
/.yalc
yalc.lock
yarn-error.log
.DS_Store
package-lock.json
+3
View File
@@ -0,0 +1,3 @@
{
"main": "dist/thirdweb-dev-auth-express.cjs.js"
}
+3
View File
@@ -0,0 +1,3 @@
{
"main": "dist/thirdweb-dev-auth-next.cjs.js"
}
-1
View File
@@ -31,7 +31,6 @@
"@microsoft/tsdoc": "^0.14.1",
"@preconstruct/cli": "^2.2.1",
"@thirdweb-dev/sdk": "*",
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
"@types/cookie": "^0.5.1",
"@types/cookie-parser": "^1.4.3",
"@types/express": "^4.17.13",
-10
View File
@@ -1,10 +0,0 @@
node_modules/
.env
coverage
coverage.json
typechain
#brownie files
cache
build
artifacts
@@ -1,66 +0,0 @@
project_structure:
build: build
contracts: contracts
interfaces: interfaces
reports: reports
scripts: scripts
tests: tests
networks:
default: development
development:
gas_limit: max
gas_buffer: 1
gas_price: 0
max_fee: null
priority_fee: null
reverting_tx_gas_limit: max
default_contract_owner: true
cmd_settings: null
live:
gas_limit: auto
gas_buffer: 1.1
gas_price: auto
max_fee: null
priority_fee: null
reverting_tx_gas_limit: false
default_contract_owner: false
compiler:
evm_version: null
solc:
version: null
optimizer:
enabled: true
runs: 200
remappings: null
vyper:
version: null
console:
show_colors: true
color_style: monokai
auto_suggest: true
completions: true
editing_mode: emacs
reports:
exclude_paths: null
exclude_contracts: null
only_include_project: true
hypothesis:
deadline: null
max_examples: 50
report_multiple_bugs: False
stateful_step_count: 10
phases:
explicit: true
reuse: true
generate: true
target: true
shrink: true
autofetch_sources: false
dependencies: null
dev_deployment_artifacts: false
@@ -1,12 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract ConstructorParams {
bytes32 public immutable contractUri;
uint256 contractId;
constructor(bytes32 uri, uint256 someId) {
contractUri = uri;
contractId = someId;
}
}
@@ -1,6 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract Greeter {
constructor() {}
}
-13
View File
@@ -1,13 +0,0 @@
node_modules/
.env
coverage
coverage.json
typechain
yarn.lock
#forge files
cache
out
artifacts
package-lock.json
yarn.lock
@@ -1,23 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract ConstructorParams {
struct Foo {
uint256 aNumber;
bytes32 aString;
address[] anArray;
}
bytes32 public immutable contractUri;
uint256 contractId;
bytes[] someCode;
Foo public foo;
constructor(bytes32 uri, uint256 someId, bytes[] memory anArray, Foo memory aStruct) {
contractUri = uri;
contractId = someId;
foo = aStruct;
someCode = anArray;
}
}
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Events is ERC20 {
event MyEvent(uint256 money);
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Greeter is ERC20 {
constructor() ERC20("MyToken", "MTK") {}
}
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GreeterWithDifferentName is ERC20 {
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,52 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@thirdweb-dev/contracts/feature/LazyMintERC721.sol";
import "@thirdweb-dev/contracts/feature/ContractMetadata.sol";
import "@thirdweb-dev/contracts/feature/PermissionsEnumerable.sol";
import "@thirdweb-dev/contracts/feature/Royalty.sol";
import "@thirdweb-dev/contracts/feature/Multicall.sol";
import "@thirdweb-dev/contracts/feature/Drop.sol";
contract SimpleDrop is ERC721, LazyMintERC721, Drop, ContractMetadata, PermissionsEnumerable, Royalty, Multicall {
constructor() ERC721("MyToken", "MTK") {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function tokenURI(uint256 _tokenId) public view override(ERC721, LazyMintERC721) returns (string memory) {
return LazyMintERC721.tokenURI(_tokenId);
}
function collectPriceOnClaim(
uint256 _quantityToClaim,
address _currency,
uint256 _pricePerToken
) internal override {
}
/// @dev Transfers the NFTs being claimed.
function transferTokensOnClaim(address _to, uint256 _quantityBeingClaimed)
internal
override
returns (uint256 startTokenId) {
return 0;
}
function _canLazyMint() internal view override returns (bool) {
return hasRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function _canSetContractURI() internal view override returns (bool) {
return hasRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function _canSetRoyaltyInfo() internal view override returns (bool) {
return hasRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function _canSetClaimConditions() internal view override returns (bool) {
return hasRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
}
@@ -1,6 +0,0 @@
[default]
remappings = [
'@openzeppelin/=node_modules/@openzeppelin/',
'@thirdweb-dev/=node_modules/@thirdweb-dev/',
]
@@ -1,10 +0,0 @@
{
"name": "foundry-project",
"private": true,
"devDependencies": {},
"dependencies": {
"@openzeppelin/contracts": "^4.5.0",
"@thirdweb-dev/contracts": "^2.3.14"
},
"scripts": {}
}
-10
View File
@@ -1,10 +0,0 @@
node_modules/
.env
coverage
coverage.json
typechain
yarn.lock
#Hardhat files
cache
artifacts
-15
View File
@@ -1,15 +0,0 @@
# Basic Sample Hardhat Project
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts.
Try running some of the following tasks:
```shell
npx hardhat accounts
npx hardhat compile
npx hardhat clean
npx hardhat test
npx hardhat node
node scripts/sample-script.js
npx hardhat help
```
@@ -1,27 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract ConstructorParams {
struct Foo {
uint256 aNumber;
bytes32 aString;
address[] anArray;
}
bytes32 public immutable contractUri;
uint256 contractId;
bytes[] someCode;
Foo public foo;
constructor(bytes32 uri, uint256 someId, bytes[] memory anArray, Foo memory aStruct) {
contractUri = uri;
contractId = someId;
foo = aStruct;
someCode = anArray;
}
function updateStruct(Foo memory aStruct) public {
foo = aStruct;
}
}
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Events is ERC20 {
event MyEvent(uint256 money);
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Greeter is ERC20 {
constructor() ERC20("MyToken", "MTK") {
_mint(msg.sender, 1000000);
}
}
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GreeterWithDifferentName is ERC20 {
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,13 +0,0 @@
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@thirdweb-dev/contracts/feature/PrimarySale.sol";
contract NFT is ERC721, PrimarySale {
constructor() ERC721("NFT", "NFT") {
}
/// @dev Determine what wallet can update claim conditions
function _canSetPrimarySaleRecipient() internal pure override returns (bool) {
return true;
}
}
@@ -1,29 +0,0 @@
require("@nomiclabs/hardhat-waffle");
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: {
version: "0.8.13",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
};
File diff suppressed because it is too large Load Diff
@@ -1,17 +0,0 @@
{
"name": "hardhat-project",
"private": true,
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"chai": "^4.3.6",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.2",
"hardhat": "^2.9.9",
"typescript": "^4.6.3"
},
"dependencies": {
"@openzeppelin/contracts": "^4.7.3",
"@thirdweb-dev/contracts": "^2.3.9"
}
}
@@ -1,32 +0,0 @@
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// When running the script with `npx hardhat run <script>` you'll find the Hardhat
// Runtime Environment's members available in the global scope.
const hre = require("hardhat");
async function main() {
// Hardhat always runs the compile task when running scripts with its command
// line interface.
//
// If this script is run directly using `node` you may want to call compile
// manually to make sure everything is compiled
// await hre.run('compile');
// We get the contract to deploy
const Greeter = await hre.ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");
await greeter.deployed();
console.log("Greeter deployed to:", greeter.address);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
@@ -1,12 +0,0 @@
node_modules/
.env
coverage
coverage.json
typechain
yarn.lock
# builder stuff
cache
artifacts
build
out
@@ -1,15 +0,0 @@
# Basic Sample Hardhat Project
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts.
Try running some of the following tasks:
```shell
npx hardhat accounts
npx hardhat compile
npx hardhat clean
npx hardhat test
npx hardhat node
node scripts/sample-script.js
npx hardhat help
```
@@ -1,66 +0,0 @@
project_structure:
build: build
contracts: contracts
interfaces: interfaces
reports: reports
scripts: scripts
tests: tests
networks:
default: development
development:
gas_limit: max
gas_buffer: 1
gas_price: 0
max_fee: null
priority_fee: null
reverting_tx_gas_limit: max
default_contract_owner: true
cmd_settings: null
live:
gas_limit: auto
gas_buffer: 1.1
gas_price: auto
max_fee: null
priority_fee: null
reverting_tx_gas_limit: false
default_contract_owner: false
compiler:
evm_version: null
solc:
version: null
optimizer:
enabled: true
runs: 200
remappings: null
vyper:
version: null
console:
show_colors: true
color_style: monokai
auto_suggest: true
completions: true
editing_mode: emacs
reports:
exclude_paths: null
exclude_contracts: null
only_include_project: true
hypothesis:
deadline: null
max_examples: 50
report_multiple_bugs: False
stateful_step_count: 10
phases:
explicit: true
reuse: true
generate: true
target: true
shrink: true
autofetch_sources: false
dependencies: null
dev_deployment_artifacts: false
@@ -1,14 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@thirdweb-dev/contracts/ThirdwebContract.sol";
contract ConstructorParams is ThirdwebContract {
bytes32 public immutable contractUri;
uint256 contractId;
constructor(bytes32 uri, uint256 someId) {
contractUri = uri;
contractId = someId;
}
}
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Events is ERC20 {
event MyEvent(uint256 money);
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,9 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@thirdweb-dev/contracts/ThirdwebContract.sol";
contract Greeter is ERC20, ThirdwebContract {
constructor() ERC20("MyToken", "MTK") {}
}
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GreeterWithDifferentName is ERC20 {
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,50 +0,0 @@
[default]
auto_detect_solc = true
block_base_fee_per_gas = 0
block_coinbase = '0x0000000000000000000000000000000000000000'
block_difficulty = 0
block_number = 0
block_timestamp = 0
bytecode_hash = 'ipfs'
cache = true
cache_path = 'cache'
evm_version = 'london'
extra_output = []
extra_output_files = []
ffi = false
force = false
fuzz_max_global_rejects = 65536
fuzz_max_local_rejects = 1024
fuzz_runs = 256
gas_limit = 9223372036854775807
gas_price = 0
gas_reports = ['*']
ignored_error_codes = [1878]
initial_balance = '0xffffffffffffffffffffffff'
libraries = []
libs = ['node_modules']
memory_limit = 33554432
names = false
no_storage_caching = false
offline = false
optimizer = true
optimizer_runs = 200
out = 'out'
remappings = [
'@openzeppelin/=node_modules/@openzeppelin/',
'@thirdweb-dev/=node_modules/@thirdweb-dev/',
'lib/=node_modules/@thirdweb-dev/contracts/contracts/lib/',
]
sender = '0x00a329c0648769a73afac7f9381e08fb43dbea72'
sizes = false
sparse_mode = false
src = 'contracts'
test = 'test'
tx_origin = '0x00a329c0648769a73afac7f9381e08fb43dbea72'
verbosity = 0
via_ir = false
[default.rpc_storage_caching]
chains = 'all'
endpoints = 'all'
@@ -1,21 +0,0 @@
require("@nomiclabs/hardhat-waffle");
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
};
File diff suppressed because it is too large Load Diff
@@ -1,19 +0,0 @@
{
"name": "multi-project",
"private": true,
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"chai": "^4.3.6",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.2",
"hardhat": "^2.9.3"
},
"dependencies": {
"@openzeppelin/contracts": "^4.7.3",
"@thirdweb-dev/contracts": "^2.3.5"
},
"scripts": {
"compile": "hardhat compile"
}
}
@@ -1,32 +0,0 @@
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// When running the script with `npx hardhat run <script>` you'll find the Hardhat
// Runtime Environment's members available in the global scope.
const hre = require("hardhat");
async function main() {
// Hardhat always runs the compile task when running scripts with its command
// line interface.
//
// If this script is run directly using `node` you may want to call compile
// manually to make sure everything is compiled
// await hre.run('compile');
// We get the contract to deploy
const Greeter = await hre.ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");
await greeter.deployed();
console.log("Greeter deployed to:", greeter.address);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
@@ -1,118 +0,0 @@
/**
* Use this file to configure your truffle project. It's seeded with some
* common settings for different networks and features like migrations,
* compilation and testing. Uncomment the ones you need or modify
* them to suit your project as necessary.
*
* More information about configuration can be found at:
*
* https://trufflesuite.com/docs/truffle/reference/configuration
*
* To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
* to sign your transactions before they're sent to a remote public node. Infura accounts
* are available for free at: infura.io/register.
*
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
* public/private key pairs. If you're publishing your code to GitHub make sure you load this
* phrase from a file you've .gitignored so it doesn't accidentally become public.
*
*/
// const HDWalletProvider = require('@truffle/hdwallet-provider');
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
// contracts_build_directory: "./build-test",
// contracts_directory: "./contracts2",
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a development blockchain for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
// Useful for testing. The `development` name is special - truffle uses it by default
// if it's defined here and no other network is specified at the command line.
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
// tab if you use this network and you must also set the `host`, `port` and `network_id`
// options below to some value.
//
// development: {
// host: "127.0.0.1", // Localhost (default: none)
// port: 8545, // Standard Ethereum port (default: none)
// network_id: "*", // Any network (default: none)
// },
// Another network with more advanced options...
// advanced: {
// port: 8777, // Custom port
// network_id: 1342, // Custom network
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
// from: <address>, // Account to send txs from (default: accounts[0])
// websocket: true // Enable EventEmitter interface for web3 (default: false)
// },
// Useful for deploying to a public network.
// NB: It's important to wrap the provider as a function.
// ropsten: {
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
// network_id: 3, // Ropsten's id
// gas: 5500000, // Ropsten has a lower block limit than mainnet
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
// },
// Useful for private networks
// private: {
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
// network_id: 2111, // This network is yours, in the cloud.
// production: true // Treats this network as if it was a public net. (default: false)
// }
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: "0.8.13", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
},
},
// Truffle DB is currently disabled by default; to enable it, change enabled:
// false to enabled: true. The default storage location can also be
// overridden by specifying the adapter settings, as shown in the commented code below.
//
// NOTE: It is not possible to migrate your contracts to truffle DB and you should
// make a backup of your artifacts to a safe location before enabling this feature.
//
// After you backed up your artifacts you can utilize db by running migrate as follows:
// $ truffle migrate --reset --compile-all
//
// db: {
// enabled: false,
// host: "127.0.0.1",
// adapter: {
// name: "sqlite",
// settings: {
// directory: ".db"
// }
// }
// }
};
-10
View File
@@ -1,10 +0,0 @@
node_modules/
.env
coverage
coverage.json
typechain
yarn.lock
#forge files
cache
artifacts
@@ -1,14 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@thirdweb-dev/contracts/ThirdwebContract.sol";
contract ConstructorParams is ThirdwebContract {
bytes32 public immutable contractUri;
uint256 contractId;
constructor(bytes32 uri, uint256 someId) {
contractUri = uri;
contractId = someId;
}
}
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Events is ERC20 {
event MyEvent(uint256 money);
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,9 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@thirdweb-dev/contracts/ThirdwebContract.sol";
contract Greeter is ERC20, ThirdwebContract {
constructor() ERC20("MyToken", "MTK") {}
}
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GreeterWithDifferentName is ERC20 {
constructor() ERC20("MyToken2", "MTK") {}
}
-36
View File
@@ -1,36 +0,0 @@
{
"name": "foundry-project",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "foundry-project",
"dependencies": {
"@openzeppelin/contracts": "^4.7.3",
"@thirdweb-dev/contracts": "^2.3.8"
}
},
"node_modules/@openzeppelin/contracts": {
"version": "4.7.3",
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz",
"integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw=="
},
"node_modules/@thirdweb-dev/contracts": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@thirdweb-dev/contracts/-/contracts-2.3.8.tgz",
"integrity": "sha512-cSVwIzPSYaS8gFlkq4r+G9UyVwr/62uE+p6SzrZFXYCbeCJwJTml3VnrVEptJ7g8RukL4Lh6uwQ6IPtgMTY4cQ=="
}
},
"dependencies": {
"@openzeppelin/contracts": {
"version": "4.7.3",
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz",
"integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw=="
},
"@thirdweb-dev/contracts": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@thirdweb-dev/contracts/-/contracts-2.3.8.tgz",
"integrity": "sha512-cSVwIzPSYaS8gFlkq4r+G9UyVwr/62uE+p6SzrZFXYCbeCJwJTml3VnrVEptJ7g8RukL4Lh6uwQ6IPtgMTY4cQ=="
}
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"name": "foundry-project",
"private": true,
"dependencies": {
"@openzeppelin/contracts": "^4.7.3",
"@thirdweb-dev/contracts": "^2.3.8"
},
"scripts": {}
}
-11
View File
@@ -1,11 +0,0 @@
node_modules/
.env
coverage
coverage.json
typechain
yarn.lock
#truffle files
cache
build
migrations
@@ -1,14 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@thirdweb-dev/contracts/ThirdwebContract.sol";
contract ConstructorParams is ThirdwebContract {
bytes32 public immutable contractUri;
uint256 contractId;
constructor(bytes32 uri, uint256 someId) {
contractUri = uri;
contractId = someId;
}
}
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Events is ERC20 {
event MyEvent(uint256 money);
constructor() ERC20("MyToken2", "MTK") {}
}
@@ -1,9 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@thirdweb-dev/contracts/ThirdwebContract.sol";
contract Greeter is ERC20, ThirdwebContract {
constructor() ERC20("MyToken", "MTK") {}
}
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GreeterWithDifferentName is ERC20 {
constructor() ERC20("MyToken2", "MTK") {}
}
File diff suppressed because it is too large Load Diff
@@ -1,10 +0,0 @@
{
"name": "truffle-project",
"private": true,
"dependencies": {
"@openzeppelin/contracts": "^4.7.3",
"@thirdweb-dev/contracts": "^2.3.8",
"truffle": "^5.5.18"
},
"scripts": {}
}
@@ -1,118 +0,0 @@
/**
* Use this file to configure your truffle project. It's seeded with some
* common settings for different networks and features like migrations,
* compilation and testing. Uncomment the ones you need or modify
* them to suit your project as necessary.
*
* More information about configuration can be found at:
*
* https://trufflesuite.com/docs/truffle/reference/configuration
*
* To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
* to sign your transactions before they're sent to a remote public node. Infura accounts
* are available for free at: infura.io/register.
*
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
* public/private key pairs. If you're publishing your code to GitHub make sure you load this
* phrase from a file you've .gitignored so it doesn't accidentally become public.
*
*/
// const HDWalletProvider = require('@truffle/hdwallet-provider');
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
// contracts_build_directory: "./build-test",
// contracts_directory: "./contracts2",
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a development blockchain for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
// Useful for testing. The `development` name is special - truffle uses it by default
// if it's defined here and no other network is specified at the command line.
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
// tab if you use this network and you must also set the `host`, `port` and `network_id`
// options below to some value.
//
// development: {
// host: "127.0.0.1", // Localhost (default: none)
// port: 8545, // Standard Ethereum port (default: none)
// network_id: "*", // Any network (default: none)
// },
// Another network with more advanced options...
// advanced: {
// port: 8777, // Custom port
// network_id: 1342, // Custom network
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
// from: <address>, // Account to send txs from (default: accounts[0])
// websocket: true // Enable EventEmitter interface for web3 (default: false)
// },
// Useful for deploying to a public network.
// NB: It's important to wrap the provider as a function.
// ropsten: {
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
// network_id: 3, // Ropsten's id
// gas: 5500000, // Ropsten has a lower block limit than mainnet
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
// },
// Useful for private networks
// private: {
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
// network_id: 2111, // This network is yours, in the cloud.
// production: true // Treats this network as if it was a public net. (default: false)
// }
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: "0.8.13", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
},
},
// Truffle DB is currently disabled by default; to enable it, change enabled:
// false to enabled: true. The default storage location can also be
// overridden by specifying the adapter settings, as shown in the commented code below.
//
// NOTE: It is not possible to migrate your contracts to truffle DB and you should
// make a backup of your artifacts to a safe location before enabling this feature.
//
// After you backed up your artifacts you can utilize db by running migrate as follows:
// $ truffle migrate --reset --compile-all
//
// db: {
// enabled: false,
// host: "127.0.0.1",
// adapter: {
// name: "sqlite",
// settings: {
// directory: ".db"
// }
// }
// }
};
-2
View File
@@ -13,7 +13,6 @@
"node": ">=14.0.0 <19"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^3.2.0",
"@types/async-retry": "1.3.0",
"@types/cross-spawn": "^6.0.2",
"@types/inquirer": "^8.2.1",
@@ -32,7 +31,6 @@
},
"dependencies": {
"@thirdweb-dev/sdk": "*",
"@web-std/file": "^3.0.2",
"async-retry": "^1.3.3",
"cbor": "^8.1.0",
"commander": "^9.1.0",
-88
View File
@@ -1,88 +0,0 @@
import { Json } from "../types";
import { File } from "@web-std/file";
/**
* Given a map of file hashes to ipfs uris, this function will hash
* all properties recursively and replace them with the ipfs uris
* from the map passed in. If a hash is missing from the map, the function
* will throw an error.
*
* @internal
*
* @param object - The object to recursively process
* @param cids - The array of file hashes to ipfs uris in the recurse order
* @returns - The processed metadata with properties pointing at ipfs in place of `File | Buffer`
*/
export function replaceFilePropertiesWithHashes(
object: Record<string, any>,
cids: string[],
) {
const keys = Object.keys(object);
for (const key in keys) {
const val = object[keys[key]];
const isFile = val instanceof File || val instanceof Buffer;
if (typeof val === "object" && !isFile) {
replaceFilePropertiesWithHashes(val, cids);
continue;
}
if (!isFile) {
continue;
}
object[keys[key]] = `ipfs://${cids.splice(0, 1)[0]}`;
}
return object;
}
/**
* Replaces all ipfs:// hashes (or any other scheme) with gateway url
* @param object
* @param scheme
* @param gatewayUrl
*/
export function replaceHashWithGatewayUrl(
object: Record<string, any>,
scheme: string,
gatewayUrl: string,
): Record<string, any> {
const keys = Object.keys(object);
for (const key in keys) {
const val = object[keys[key]];
object[keys[key]] = resolveGatewayUrl(val, scheme, gatewayUrl);
if (Array.isArray(val)) {
for (const el of val) {
replaceHashWithGatewayUrl(el, scheme, gatewayUrl);
}
}
if (typeof val === "object") {
replaceHashWithGatewayUrl(val, scheme, gatewayUrl);
}
}
return object;
}
/**
* Resolves the full URL of a file for a given gateway.
*
* For example, if the hash of a file is `ipfs://bafkreib3u2u6ir2fsl5nkuwixfsb3l4xehri3psjv5yga4inuzsjunk2sy`, then the URL will be:
* "https://cloudflare-ipfs.com/ipfs/bafkreibnwjhx5s3r2rggdoy3hw7lr7wmgy4bas35oky3ed6eijklk2oyvq"
* if the gateway is `cloudflare-ipfs.com`.
*
* @param ipfsHash
* @param scheme
* @param gatewayUrl
*/
export function resolveGatewayUrl<T extends Json>(
ipfsHash: T,
scheme: string,
gatewayUrl: string,
): T {
if (typeof ipfsHash === "string") {
return ipfsHash && ipfsHash.toLowerCase().includes(scheme)
? (ipfsHash.replace(scheme, gatewayUrl) as T)
: ipfsHash;
} else {
return ipfsHash;
}
}
@@ -1,96 +0,0 @@
import { FileOrBuffer, JsonObject } from "../types";
/**
* @internal
*/
export interface UploadMetadataBatchResult {
// base cid of the directory
baseUri: string;
// path to each of the file within the directory, included full cid path
metadataUris: string[];
}
/**
* @public
*/
export interface IStorage {
/**
* Fetches a one-time-use upload token that can used to upload
* a file to storage.
*
* @returns - The one time use token that can be passed to the Pinata API.
*/
getUploadToken(contractAddress: string): Promise<string>;
/**
* Fetches data from storage. This method expects to fetch JSON formatted data
*
* @param hash - The Hash of the file to fetch
* @returns - The data, if found.
*/
get(hash: string): Promise<Record<string, any>>;
/**
* Uploads a file to the storage.
*
* @param data - The data to be uploaded. Can be a file/buffer (which will be loaded), or a string.
* @param contractAddress - Optional. The contract address the data belongs to.
* @param signerAddress - Optional. The address of the signer.
*
* @returns - The hash of the uploaded data.
*/
upload(
data: string | FileOrBuffer,
contractAddress?: string,
signerAddress?: string,
): Promise<string>;
/**
* Uploads a folder to storage.
*
* @param files - An array of the data to be uploaded. Can be a files or buffers (which will be loaded), or strings. (can be mixed, too)
* @param fileStartNumber - Optional. The first file file name begins with.
* @param contractAddress - Optional. The contract address the data belongs to.
* @param signerAddress - Optional. The address of the signer.
*
* @returns - The CID of the uploaded folder.
*/
uploadBatch(
files: (string | FileOrBuffer)[],
fileStartNumber?: number,
contractAddress?: string,
signerAddress?: string,
): Promise<UploadMetadataBatchResult>;
/**
*
* Uploads JSON metadata to IPFS
*
* @param metadata - The metadata to be uploaded.
* @param contractAddress - Optional. The contract address the data belongs to.
* @param signerAddress - Optional. The address of the signer.
*/
uploadMetadata(
metadata: JsonObject,
contractAddress?: string,
signerAddress?: string,
): Promise<string>;
/**
*
* Uploads JSON metadata to IPFS
*
* @param metadata - The metadata to be uploaded.
* @param fileStartNumber - Optional. The first file file name begins with.
* @param contractAddress - Optional. The contract address the data belongs to.
* @param signerAddress - Optional. The address of the signer.
*/
uploadMetadataBatch(
metadatas: JsonObject[],
fileStartNumber?: number,
contractAddress?: string,
signerAddress?: string,
): Promise<UploadMetadataBatchResult>;
}
@@ -1,21 +0,0 @@
import { FileOrBuffer } from "../types";
/**
* @internal
*/
export interface CidWithFileName {
// base cid of the directory
cid: string;
// file name of the file without cid
fileNames: string[];
}
export interface IStorageUpload {
uploadBatchWithCid(
files: (string | FileOrBuffer)[],
fileStartNumber?: number,
contractAddress?: string,
signerAddress?: string,
): Promise<CidWithFileName>;
}
-10
View File
@@ -1,10 +0,0 @@
export type BufferOrStringWithName = {
data: Buffer | string;
name?: string;
};
export type FileOrBuffer = Buffer | BufferOrStringWithName;
type JsonLiteral = boolean | null | number | string;
type JsonLiteralOrFileOrBuffer = JsonLiteral | FileOrBuffer;
export type Json = JsonLiteralOrFileOrBuffer | JsonObject | Json[];
export type JsonObject = { [key: string]: Json };
-1
View File
@@ -39,7 +39,6 @@
"@microsoft/api-extractor": "^7.19.4",
"@microsoft/tsdoc": "^0.14.1",
"@preconstruct/cli": "^2.2.1",
"@trivago/prettier-plugin-sort-imports": "^3.2.0",
"@types/color": "^3.0.3",
"@types/mime": "^3.0.1",
"@types/react": "^18.0.5",
-18
View File
@@ -1,18 +0,0 @@
node_modules/
typechain/
lib/
temp/
bin/
dist/
.idea
.vscode
yarn-error.log
.DS_Store
.parcel-cache/
tsconfig.tsbuildinfo
test/test_dump/*
.yalc/
.swc/
yalc.lock
abis/
package-lock.json
-1
View File
@@ -80,7 +80,6 @@
"merkletreejs": "^0.2.24",
"@thirdweb-dev/contracts-js": "*",
"@thirdweb-dev/storage": "*",
"@web-std/file": "^3.0.0",
"cbor": "^8.1.0",
"cross-fetch": "^3.1.5",
"eventemitter3": "^4.0.7",
-153
View File
@@ -1,153 +0,0 @@
import { Json } from "../types";
import { File } from "@web-std/file";
/**
* Given a map of file hashes to ipfs uris, this function will hash
* all properties recursively and replace them with the ipfs uris
* from the map passed in. If a hash is missing from the map, the function
* will throw an error.
*
* @internal
*
* @param object - The object to recursively process
* @param cids - The array of file hashes to ipfs uris in the recurse order
* @returns - The processed metadata with properties pointing at ipfs in place of `File | Buffer`
*/
export function replaceFilePropertiesWithHashes(
object: Record<string, any>,
cids: string[],
) {
const keys = Object.keys(object);
for (const key in keys) {
const val = object[keys[key]];
const isFile = val instanceof File || val instanceof Buffer;
if (typeof val === "object" && !isFile) {
replaceFilePropertiesWithHashes(val, cids);
continue;
}
if (!isFile) {
continue;
}
object[keys[key]] = `ipfs://${cids.splice(0, 1)[0]}`;
}
return object;
}
/**
* Replaces all ipfs:// hashes (or any other scheme) with gateway url
* @internal
* @param object
* @param scheme
* @param gatewayUrl
*/
export function replaceHashWithGatewayUrl(
object: Record<string, any>,
scheme: string,
gatewayUrl: string,
): Record<string, any> {
if (object === null || !object) {
return {};
}
const keys = Object.keys(object);
for (const key in keys) {
const val = object[keys[key]];
object[keys[key]] = resolveGatewayUrl(val, scheme, gatewayUrl);
if (Array.isArray(val)) {
object[keys[key]] = val.map((el) => {
if (typeof el === "object") {
return replaceHashWithGatewayUrl(el, scheme, gatewayUrl);
} else {
return resolveGatewayUrl(el, scheme, gatewayUrl);
}
});
}
if (typeof val === "object") {
replaceHashWithGatewayUrl(val, scheme, gatewayUrl);
}
}
return object;
}
/**
* Replaces all gateway urls back to ipfs:// hashes
* @internal
* @param object
* @param scheme
* @param gatewayUrl
*/
export function replaceGatewayUrlWithHash(
object: Record<string, any>,
scheme: string,
gatewayUrl: string,
): Record<string, any> {
if (object === null || !object) {
return {};
}
const keys = Object.keys(object);
for (const key in keys) {
const val = object[keys[key]];
object[keys[key]] = toIPFSHash(val, scheme, gatewayUrl);
if (Array.isArray(val)) {
object[keys[key]] = val.map((el) => {
const isFile = el instanceof File || el instanceof Buffer;
if (typeof el === "object" && !isFile) {
return replaceGatewayUrlWithHash(el, scheme, gatewayUrl);
} else {
return toIPFSHash(el, scheme, gatewayUrl);
}
});
}
const isFile = val instanceof File || val instanceof Buffer;
if (typeof val === "object" && !isFile) {
replaceGatewayUrlWithHash(val, scheme, gatewayUrl);
}
}
return object;
}
/**
* Resolves the full URL of a file for a given gateway.
*
* For example, if the hash of a file is `ipfs://bafkreib3u2u6ir2fsl5nkuwixfsb3l4xehri3psjv5yga4inuzsjunk2sy`, then the URL will be:
* "https://cloudflare-ipfs.com/ipfs/bafkreibnwjhx5s3r2rggdoy3hw7lr7wmgy4bas35oky3ed6eijklk2oyvq"
* if the gateway is `cloudflare-ipfs.com`.
* @internal
* @param object
* @param scheme
* @param gatewayUrl
*/
export function resolveGatewayUrl<T extends Json>(
object: T,
scheme: string,
gatewayUrl: string,
): T {
if (typeof object === "string") {
return object && object.toLowerCase().includes(scheme)
? (object.replace(scheme, gatewayUrl) as T)
: object;
} else {
return object;
}
}
/**
* @internal
* @param object
* @param scheme
* @param gatewayUrl
*/
export function toIPFSHash<T extends Json>(
object: T,
scheme: string,
gatewayUrl: string,
): T {
if (typeof object === "string") {
return object && object.toLowerCase().includes(gatewayUrl)
? (object.replace(gatewayUrl, scheme) as T)
: object;
} else {
return object;
}
}
+3 -4
View File
@@ -1,6 +1,6 @@
import { BigNumber, BytesLike, CallOverrides, Signer, providers } from "ethers";
import type { CONTRACTS_MAP, KNOWN_CONTRACTS_MAP } from "../contracts/maps";
import { FileOrBuffer } from "@thirdweb-dev/storage";
import { BigNumber, BytesLike, CallOverrides, Signer, providers } from "ethers";
// --- utility types extracted from from ts-toolbelt --- //
@@ -47,11 +47,10 @@ export type BufferOrStringWithName = {
};
type JsonLiteral = boolean | null | number | string;
type JsonLiteralOrFileOrBuffer = JsonLiteral;
type JsonLiteralOrFileOrBuffer = JsonLiteral | FileOrBuffer;
export type Json = JsonLiteralOrFileOrBuffer | JsonObject | Json[];
export type JsonObject = { [key: string]: Json };
type TransactionResultWithMetadata<T = unknown> = {
receipt: providers.TransactionReceipt;
data: () => Promise<T>;
@@ -1,11 +1,7 @@
import {
AddressSchema,
BasisPointsSchema,
FileBufferOrStringSchema,
JsonSchema,
} from "../../shared";
import { z } from "zod";
import { AddressSchema, BasisPointsSchema, JsonSchema } from "../../shared";
import { FileBufferOrStringSchema } from "@thirdweb-dev/storage";
import { constants } from "ethers";
import { z } from "zod";
/**
* @internal
+5 -9
View File
@@ -1,3 +1,6 @@
import { toSemver } from "../../common/index";
import { ChainId, CONTRACT_ADDRESSES } from "../../constants/index";
import { AddressSchema, BigNumberishSchema, JsonSchema } from "../shared";
import {
CommonContractOutputSchema,
CommonContractSchema,
@@ -8,16 +11,9 @@ import {
CommonTrustedForwarderSchema,
MerkleSchema,
} from "./common";
import { z } from "zod";
import {
AddressSchema,
BigNumberishSchema,
FileBufferOrStringSchema,
JsonSchema,
} from "../shared";
import { FileBufferOrStringSchema } from "@thirdweb-dev/storage";
import { BigNumberish } from "ethers";
import { toSemver } from "../../common/index";
import { ChainId, CONTRACT_ADDRESSES } from "../../constants/index";
import { z } from "zod";
/**
* @internal
-15
View File
@@ -1,24 +1,9 @@
import { isBrowser } from "../common/utils";
import { Json } from "../core/types";
import { File } from "@web-std/file";
import { BigNumber, CallOverrides, utils } from "ethers";
import { z } from "zod";
export const MAX_BPS = 10_000;
const fileOrBufferUnion = isBrowser()
? ([z.instanceof(File), z.string()] as [
z.ZodType<InstanceType<typeof File>>,
z.ZodString,
])
: ([z.instanceof(Buffer), z.string()] as [
z.ZodTypeAny, // @fixme, this is a hack to make browser happy for now
z.ZodString,
]);
export const FileBufferOrStringSchema = z.union(fileOrBufferUnion);
export type FileBufferOrString = z.output<typeof FileBufferOrStringSchema>;
export const BytesLikeSchema = z.union([z.array(z.number()), z.string()]);
export const BigNumberSchema = z
@@ -1,11 +1,7 @@
import { z } from "zod";
import {
BigNumberSchema,
FileBufferOrStringSchema,
HexColor,
JsonSchema,
} from "../../shared";
import { BigNumberSchema, HexColor, JsonSchema } from "../../shared";
import { OptionalPropertiesInput } from "./properties";
import { FileBufferOrStringSchema } from "@thirdweb-dev/storage";
import { z } from "zod";
/**
* @internal
@@ -1,5 +1,5 @@
import { FileBufferOrString } from "@thirdweb-dev/storage";
import { BigNumberish } from "ethers";
import { FileBufferOrString } from "../../schema";
/**
* Options for deploying an NFT contract
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -6
View File
@@ -1,5 +1,5 @@
/* eslint-disable turbo/no-undeclared-env-vars */
import { EditionDrop, ThirdwebSDK } from "../src";
import { ThirdwebSDK } from "../src";
import { ethers, Wallet } from "ethers";
const RPC_URL = "https://rpc-mumbai.maticvigil.com/";
@@ -7,8 +7,6 @@ const RPC_URL = "https://rpc-mumbai.maticvigil.com/";
global.fetch = require("cross-fetch");
describe("Gasless Forwarder", async () => {
let bundleDropContract: EditionDrop;
it.skip("should use sdk with biconomy", async () => {
const BUNDLE_DROP_ADDRESS = "0xEBed8e37a32660dbCeeeC19cCBb952b7d214f008";
const provider = ethers.getDefaultProvider(RPC_URL);
@@ -22,7 +20,7 @@ describe("Gasless Forwarder", async () => {
},
});
const bundleDrop = sdk.getEditionDrop(BUNDLE_DROP_ADDRESS);
await bundleDrop.claim("0", 1, false, []);
await bundleDrop.claim("0", 1);
});
it.skip("should use sdk with openzeppelin defender", async () => {
@@ -36,7 +34,5 @@ describe("Gasless Forwarder", async () => {
},
},
});
// const bundleDrop = sdk.getBundleDropContract(BUNDLE_DROP_ADDRESS);
// await bundleDrop.claim("0", 1, []);
});
});
+17 -11
View File
@@ -1,8 +1,13 @@
import { FileOrBuffer, JsonObject } from "../../src/core/types";
import { v4 as uuidv4 } from "uuid";
import { NotFoundError } from "../../src";
import { File } from "@web-std/file";
import { IStorage, UploadResult } from "@thirdweb-dev/storage";
import { JsonObject } from "../../src/core/types";
import {
FileOrBuffer,
isBufferInstance,
isFileInstance,
IStorage,
UploadResult,
} from "@thirdweb-dev/storage";
import { v4 as uuidv4 } from "uuid";
export class MockStorage implements IStorage {
private objects: { [key: string]: any } = {};
@@ -16,9 +21,9 @@ export class MockStorage implements IStorage {
const uuid = uuidv4();
let serializedData = "";
if (data instanceof File) {
if (isFileInstance(data)) {
serializedData = await data.text();
} else if (data instanceof Buffer) {
} else if (isBufferInstance(data)) {
serializedData = data.toString();
} else if (typeof data === "string") {
serializedData = data;
@@ -42,15 +47,16 @@ export class MockStorage implements IStorage {
let index = fileStartNumber ? fileStartNumber : 0;
for (const file of files) {
let contents: string;
if (file instanceof File) {
if (isFileInstance(file)) {
contents = await file.text();
} else if (file instanceof Buffer) {
} else if (isBufferInstance(file)) {
contents = file.toString();
} else if (typeof file === "string") {
contents = file;
} else {
contents =
file.data instanceof Buffer ? file.data.toString() : file.data;
contents = isBufferInstance(file.data)
? file.data.toString()
: file.data;
const name = file.name ? file.name : `file_${index}`;
this.folders.cid[name] = contents;
continue;
@@ -142,7 +148,7 @@ export class MockStorage implements IStorage {
const keys = Object.keys(object).sort();
for (const key in keys) {
const val = object[keys[key]];
const shouldUpload = val instanceof File || val instanceof Buffer;
const shouldUpload = isFileInstance(val) || isBufferInstance(val);
if (shouldUpload) {
object[keys[key]] = await this.upload(val);
}
-1
View File
@@ -26,7 +26,6 @@
"@microsoft/api-extractor": "^7.29.2",
"@microsoft/tsdoc": "^0.14.1",
"@preconstruct/cli": "^2.2.1",
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
"@typescript-eslint/eslint-plugin": "^5.33.0",
"@typescript-eslint/parser": "^5.33.0",
"eslint": "^8.21.0",
-15
View File
@@ -1,20 +1,5 @@
import { isBrowser } from "../utils/context";
import { File } from "@web-std/file";
import { z } from "zod";
const fileOrBufferUnion = isBrowser()
? ([z.instanceof(File), z.string()] as [
z.ZodType<InstanceType<typeof File>>,
z.ZodString,
])
: ([z.instanceof(Buffer), z.string()] as [
z.ZodTypeAny, // @fixme, this is a hack to make browser happy for now
z.ZodString,
]);
export const FileBufferOrStringSchema = z.union(fileOrBufferUnion);
export type FileBufferOrString = z.output<typeof FileBufferOrStringSchema>;
export const MAX_BPS = 10_000;
export const BasisPointsSchema = z
.number()
+2 -1
View File
@@ -1,4 +1,5 @@
import { FileBufferOrStringSchema, JsonSchema } from "./common";
import { JsonSchema } from "./common";
import { FileBufferOrStringSchema } from "@thirdweb-dev/storage";
import { z } from "zod";
/**
+2 -6
View File
@@ -1,9 +1,5 @@
import {
FileBufferOrStringSchema,
HexColor,
JsonSchema,
OptionalPropertiesInput,
} from "./common";
import { HexColor, JsonSchema, OptionalPropertiesInput } from "./common";
import { FileBufferOrStringSchema } from "@thirdweb-dev/storage";
import { z } from "zod";
/**
-7
View File
@@ -1,7 +0,0 @@
/node_modules
/dist
/.yalc
yalc.lock
yarn-error.log
.DS_Store
package-lock.json
+2 -4
View File
@@ -26,7 +26,6 @@
"@babel/preset-env": "^7.18.10",
"@babel/preset-typescript": "^7.18.6",
"@preconstruct/cli": "^2.2.1",
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
"@types/chai": "^4.3.3",
"@types/mocha": "^9.1.1",
"@typescript-eslint/eslint-plugin": "^5.33.1",
@@ -35,14 +34,13 @@
"eslint": "^8.22.0",
"esm": "^3.2.25",
"mocha": "^10.0.0",
"prettier": "^2.7.1",
"ts-mocha": "^10.0.0",
"tsc": "^2.0.4",
"typescript": "^4.7.4"
},
"dependencies": {
"@web-std/file": "^3.0.2",
"cross-fetch": "^3.1.5",
"form-data": "^4.0.0"
"form-data": "^4.0.0",
"zod": "^3.18.0"
}
}
+21 -20
View File
@@ -4,6 +4,8 @@ import {
PUBLIC_GATEWAYS,
} from "../constants/urls";
import {
isBufferInstance,
isFileInstance,
replaceFilePropertiesWithHashes,
replaceGatewayUrlWithHash,
replaceHashWithGatewayUrl,
@@ -14,7 +16,6 @@ import { IStorageUpload, UploadResult } from "../interfaces/IStorageUpload";
import { FileOrBuffer, JsonObject } from "../types";
import { UploadProgressEvent } from "../types/events";
import { PinataUploader } from "../uploaders/pinata-uploader";
import { File } from "@web-std/file";
import fetch from "cross-fetch";
import FormData from "form-data";
@@ -34,7 +35,7 @@ export class IpfsStorage implements IStorage {
constructor(
gatewayUrl: string = DEFAULT_IPFS_GATEWAY,
uploader: IStorageUpload = new PinataUploader()
uploader: IStorageUpload = new PinataUploader(),
) {
this.gatewayUrl = `${gatewayUrl.replace(/\/$/, "")}/`;
this.uploader = uploader;
@@ -42,7 +43,7 @@ export class IpfsStorage implements IStorage {
private getNextPublicGateway() {
const urlsToTry = PUBLIC_GATEWAYS.filter(
(url) => !this.failedUrls.includes(url)
(url) => !this.failedUrls.includes(url),
).filter((url) => url !== this.gatewayUrl);
if (urlsToTry.length > 0) {
return urlsToTry[0];
@@ -69,14 +70,14 @@ export class IpfsStorage implements IStorage {
signerAddress?: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
): Promise<string> {
const { cid, fileNames } = await this.uploader.uploadBatchWithCid(
[data],
0,
contractAddress,
signerAddress,
options
options,
);
const baseUri = `ipfs://${cid}/`;
@@ -93,14 +94,14 @@ export class IpfsStorage implements IStorage {
signerAddress?: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
) {
const { cid, fileNames } = await this.uploader.uploadBatchWithCid(
files,
fileStartNumber,
contractAddress,
signerAddress,
options
options,
);
const baseUri = `ipfs://${cid}/`;
@@ -137,7 +138,7 @@ export class IpfsStorage implements IStorage {
signerAddress?: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
): Promise<string> {
// since there's only single object, always use the first index
const { uris } = await this.uploadMetadataBatch(
@@ -145,7 +146,7 @@ export class IpfsStorage implements IStorage {
0,
contractAddress,
signerAddress,
options
options,
);
return uris[0];
}
@@ -160,7 +161,7 @@ export class IpfsStorage implements IStorage {
signerAddress?: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
): Promise<UploadResult> {
const metadataToUpload = (
await this.batchUploadProperties(metadatas, options)
@@ -170,7 +171,7 @@ export class IpfsStorage implements IStorage {
metadataToUpload,
fileStartNumber,
contractAddress,
signerAddress
signerAddress,
);
const baseUri = `ipfs://${cid}/`;
@@ -224,17 +225,17 @@ export class IpfsStorage implements IStorage {
metadatas: JsonObject[],
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
) {
// replace all active gateway url links with their raw ipfs hash
const sanitizedMetadatas = replaceGatewayUrlWithHash(
metadatas,
"ipfs://",
this.gatewayUrl
this.gatewayUrl,
);
// extract any binary file to upload
const filesToUpload = sanitizedMetadatas.flatMap((m: JsonObject) =>
this.buildFilePropertiesMap(m, [])
this.buildFilePropertiesMap(m, []),
);
// if no binary files to upload, return the metadata
if (filesToUpload.length === 0) {
@@ -246,7 +247,7 @@ export class IpfsStorage implements IStorage {
undefined,
undefined,
undefined,
options
options,
);
const cids = [];
@@ -269,7 +270,7 @@ export class IpfsStorage implements IStorage {
*/
private buildFilePropertiesMap(
object: JsonObject,
files: (File | Buffer)[] = []
files: (File | Buffer)[] = [],
): (File | Buffer)[] {
if (Array.isArray(object)) {
object.forEach((element) => {
@@ -278,7 +279,7 @@ export class IpfsStorage implements IStorage {
} else if (object) {
const values = Object.values(object);
for (const val of values) {
if (val instanceof File || val instanceof Buffer) {
if (isFileInstance(val) || isBufferInstance(val)) {
files.push(val);
} else if (typeof val === "object") {
this.buildFilePropertiesMap(val as JsonObject, files);
@@ -298,11 +299,11 @@ export class IpfsStorage implements IStorage {
public async uploadSingle(
data: string | Record<string, any>,
contractAddress?: string,
signerAddress?: string
signerAddress?: string,
): Promise<string> {
// TODO move down to IStorageUpload
const token = await (this.uploader as PinataUploader).getUploadToken(
contractAddress || ""
contractAddress || "",
);
const metadata = {
name: `CONSOLE-TS-SDK-${contractAddress}`,
@@ -320,7 +321,7 @@ export class IpfsStorage implements IStorage {
"pinataOptions",
JSON.stringify({
wrapWithDirectory: false,
})
}),
);
const res = await fetch(PINATA_IPFS_URL, {
method: "POST",
+14 -14
View File
@@ -1,8 +1,8 @@
import { isBufferInstance, isFileInstance } from "../helpers/storage";
import { IStorage } from "../interfaces/IStorage";
import { UploadResult } from "../interfaces/IStorageUpload";
import { FileOrBuffer, JsonObject } from "../types";
import { UploadProgressEvent } from "../types/events";
import { File } from "@web-std/file";
/**
* Fetch and upload files to IPFS or any other storage.
@@ -70,13 +70,13 @@ export class RemoteStorage {
data: FileOrBuffer[] | JsonObject[] | FileOrBuffer | JsonObject,
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
): Promise<UploadResult> {
if (!Array.isArray(data)) {
if (
data instanceof File ||
data instanceof Buffer ||
(data.name && data.data && data.data instanceof Buffer)
isFileInstance(data) ||
isBufferInstance(data) ||
(data.name && data.data && isBufferInstance(data.data))
) {
return this.uploadBatch([data as FileOrBuffer], options);
} else {
@@ -86,12 +86,12 @@ export class RemoteStorage {
const allFiles = (data as any[]).filter(
(item: any) =>
item instanceof File ||
item instanceof Buffer ||
(item.name && item.data && item.data instanceof Buffer)
isFileInstance(item) ||
isBufferInstance(item) ||
(item.name && item.data && isBufferInstance(item.data)),
);
const allObjects = (data as any[]).filter(
(item: any) => !(item instanceof File) && !(item instanceof Buffer)
(item: any) => !isFileInstance(item) && !isBufferInstance(item),
);
if (allFiles.length === data.length) {
return this.uploadBatch(data as FileOrBuffer[], options);
@@ -99,7 +99,7 @@ export class RemoteStorage {
return this.uploadMetadataBatch(data as JsonObject[], options);
} else {
throw new Error(
"Data to upload must be either all files or all JSON objects"
"Data to upload must be either all files or all JSON objects",
);
}
}
@@ -108,14 +108,14 @@ export class RemoteStorage {
files: FileOrBuffer[],
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
): Promise<UploadResult> {
return await this.storage.uploadBatch(
files,
undefined,
undefined,
undefined,
options
options,
);
}
@@ -123,14 +123,14 @@ export class RemoteStorage {
metadatas: JsonObject[],
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
): Promise<UploadResult> {
return await this.storage.uploadMetadataBatch(
metadatas,
undefined,
undefined,
undefined,
options
options,
);
}
}
+16 -9
View File
@@ -1,5 +1,12 @@
import { Json } from "../types";
import { File } from "@web-std/file";
export function isFileInstance(data: any): data is File {
return global.File && data instanceof File;
}
export function isBufferInstance(data: any): data is Buffer {
return global.Buffer && data instanceof Buffer;
}
/**
* Given a map of file hashes to ipfs uris, this function will hash
@@ -15,12 +22,12 @@ import { File } from "@web-std/file";
*/
export function replaceFilePropertiesWithHashes(
object: Record<string, any>,
cids: string[]
cids: string[],
) {
const keys = Object.keys(object);
for (const key in keys) {
const val = object[keys[key]];
const isFile = val instanceof File || val instanceof Buffer;
const isFile = isFileInstance(val) || isBufferInstance(val);
if (typeof val === "object" && !isFile) {
replaceFilePropertiesWithHashes(val, cids);
continue;
@@ -45,7 +52,7 @@ export function replaceFilePropertiesWithHashes(
export function replaceHashWithGatewayUrl(
object: Record<string, any>,
scheme: string,
gatewayUrl: string
gatewayUrl: string,
): Record<string, any> {
if (object === null || !object) {
return {};
@@ -80,7 +87,7 @@ export function replaceHashWithGatewayUrl(
export function replaceGatewayUrlWithHash(
object: Record<string, any>,
scheme: string,
gatewayUrl: string
gatewayUrl: string,
): Record<string, any> {
if (object === null || !object) {
return {};
@@ -91,7 +98,7 @@ export function replaceGatewayUrlWithHash(
object[keys[key]] = toIPFSHash(val, scheme, gatewayUrl);
if (Array.isArray(val)) {
object[keys[key]] = val.map((el) => {
const isFile = el instanceof File || el instanceof Buffer;
const isFile = isFileInstance(el) || isBufferInstance(el);
if (typeof el === "object" && !isFile) {
return replaceGatewayUrlWithHash(el, scheme, gatewayUrl);
} else {
@@ -99,7 +106,7 @@ export function replaceGatewayUrlWithHash(
}
});
}
const isFile = val instanceof File || val instanceof Buffer;
const isFile = isFileInstance(val) || isBufferInstance(val);
if (typeof val === "object" && !isFile) {
replaceGatewayUrlWithHash(val, scheme, gatewayUrl);
}
@@ -121,7 +128,7 @@ export function replaceGatewayUrlWithHash(
export function resolveGatewayUrl<T extends Json>(
object: T,
scheme: string,
gatewayUrl: string
gatewayUrl: string,
): T {
if (typeof object === "string") {
return object && object.toLowerCase().includes(scheme)
@@ -141,7 +148,7 @@ export function resolveGatewayUrl<T extends Json>(
export function toIPFSHash<T extends Json>(
object: T,
scheme: string,
gatewayUrl: string
gatewayUrl: string,
): T {
if (typeof object === "string") {
return object && object.toLowerCase().includes(gatewayUrl)
+2
View File
@@ -2,3 +2,5 @@ export * from "./interfaces/IStorage";
export * from "./interfaces/IStorageUpload";
export * from "./core/ipfs-storage";
export * from "./core/remote-storage";
export * from "./types/index";
export { isBufferInstance, isFileInstance } from "./helpers/storage";
+17
View File
@@ -1,3 +1,5 @@
import { z } from "zod";
export type BufferOrStringWithName = {
data: Buffer | string;
name?: string;
@@ -9,3 +11,18 @@ type JsonLiteral = boolean | null | number | string;
type JsonLiteralOrFileOrBuffer = JsonLiteral | FileOrBuffer;
export type Json = JsonLiteralOrFileOrBuffer | JsonObject | Json[];
export type JsonObject = { [key: string]: Json };
export const isBrowser = () => typeof window !== "undefined";
const fileOrBufferUnion = isBrowser()
? ([z.instanceof(File), z.string()] as [
z.ZodType<InstanceType<typeof File>>,
z.ZodString,
])
: ([z.instanceof(Buffer), z.string()] as [
z.ZodTypeAny, // @fixme, this is a hack to make browser happy for now
z.ZodString,
]);
export const FileBufferOrStringSchema = z.union(fileOrBufferUnion);
export type FileBufferOrString = z.output<typeof FileBufferOrStringSchema>;
@@ -1,8 +1,8 @@
import { PINATA_IPFS_URL, TW_IPFS_SERVER_URL } from "../constants/urls";
import { isBufferInstance, isFileInstance } from "../helpers/storage";
import { CidWithFileName, IStorageUpload } from "../interfaces/IStorageUpload";
import { FileOrBuffer } from "../types";
import { UploadProgressEvent } from "../types/events";
import { File } from "@web-std/file";
import FormData from "form-data";
/**
@@ -37,7 +37,7 @@ export class PinataUploader implements IStorageUpload {
signerAddress?: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
}
},
): Promise<CidWithFileName> {
const token = await this.getUploadToken(contractAddress || "");
@@ -47,7 +47,7 @@ export class PinataUploader implements IStorageUpload {
files,
fileStartNumber,
contractAddress,
signerAddress
signerAddress,
);
if (typeof window === "undefined") {
@@ -123,7 +123,7 @@ export class PinataUploader implements IStorageUpload {
files: (string | FileOrBuffer)[],
fileStartNumber = 0,
contractAddress?: string,
signerAddress?: string
signerAddress?: string,
) {
const metadata = {
name: `CONSOLE-TS-SDK-${contractAddress}`,
@@ -141,7 +141,7 @@ export class PinataUploader implements IStorageUpload {
// if it is a file, we passthrough the file extensions,
// if it is a buffer or string, the filename would be fileStartNumber + index
// if it is a buffer or string with names, the filename would be the name
if (file instanceof File) {
if (isFileInstance(file)) {
let extensions = "";
if (file.name) {
const extensionStartIndex = file.name.lastIndexOf(".");
@@ -150,10 +150,10 @@ export class PinataUploader implements IStorageUpload {
}
}
fileName = `${i + fileStartNumber}${extensions}`;
} else if (file instanceof Buffer || typeof file === "string") {
} else if (isBufferInstance(file) || typeof file === "string") {
fileName = `${i + fileStartNumber}`;
} else if (file && file.name && file?.data) {
fileData = file?.data;
} else if (file && file.name && (file as any)?.data) {
fileData = (file as any)?.data;
fileName = `${file.name}`;
} else {
// default behavior
@@ -163,7 +163,7 @@ export class PinataUploader implements IStorageUpload {
const filepath = `files/${fileName}`;
if (fileNames.indexOf(fileName) > -1) {
throw new Error(
`DUPLICATE_FILE_NAME_ERROR: File name ${fileName} was passed for more than one file.`
`DUPLICATE_FILE_NAME_ERROR: File name ${fileName} was passed for more than one file.`,
);
}
fileNames.push(fileName);
+20 -20
View File
@@ -15,7 +15,7 @@ describe("IPFS Uploads", async () => {
async function getFile(upload: string): Promise<Response> {
const response = await fetch(
`${ipfsGatewayUrl}${upload.replace("ipfs://", "")}`
`${ipfsGatewayUrl}${upload.replace("ipfs://", "")}`,
)
.then(async (res) => {
return res;
@@ -69,7 +69,7 @@ describe("IPFS Uploads", async () => {
it("should upload null metadata", async () => {
try {
const metadata = JSON.parse(
readFileSync("test/files/metadata.json", "utf8")
readFileSync("test/files/metadata.json", "utf8"),
);
const upload = await storage.uploadMetadataBatch([metadata]);
assert.isTrue(upload.uris.length > 0);
@@ -85,7 +85,7 @@ describe("IPFS Uploads", async () => {
const otherStorage = new IpfsStorage(PUBLIC_GATEWAYS[1]);
const downloaded = await otherStorage.get(upload);
expect(downloaded.svg).to.eq(
`${PUBLIC_GATEWAYS[1]}QmZsU8nTTexTxPzCKZKqo3Ntf5cUiWMRahoLmtpimeaCiT/backgrounds/SVG/Asset%20501.svg`
`${PUBLIC_GATEWAYS[1]}QmZsU8nTTexTxPzCKZKqo3Ntf5cUiWMRahoLmtpimeaCiT/backgrounds/SVG/Asset%20501.svg`,
);
});
@@ -104,7 +104,7 @@ describe("IPFS Uploads", async () => {
onProgress: () => {
updates += 1;
},
}
},
);
expect(updates).to.be.greaterThan(0);
@@ -139,7 +139,7 @@ describe("IPFS Uploads", async () => {
});
assert.equal(
upload,
"ipfs://QmYKJLPfwKduSfWgdLLt49SE6LvzkGzxeYMCkhXWbpJam7/0"
"ipfs://QmYKJLPfwKduSfWgdLLt49SE6LvzkGzxeYMCkhXWbpJam7/0",
);
});
@@ -149,7 +149,7 @@ describe("IPFS Uploads", async () => {
});
assert.equal(
upload,
"ipfs://QmbaNzUcv7KPgdwq9u2qegcptktpUK6CdRZF72eSjSa6iJ/0"
"ipfs://QmbaNzUcv7KPgdwq9u2qegcptktpUK6CdRZF72eSjSa6iJ/0",
);
});
@@ -159,12 +159,12 @@ describe("IPFS Uploads", async () => {
});
assert.equal(
upload,
"ipfs://QmbaNzUcv7KPgdwq9u2qegcptktpUK6CdRZF72eSjSa6iJ/0"
"ipfs://QmbaNzUcv7KPgdwq9u2qegcptktpUK6CdRZF72eSjSa6iJ/0",
);
const meta = await storage.get(upload);
assert.equal(
meta.animation_url,
`${ipfsGatewayUrl}QmUphf8LnNGdFwBevnxNkq8dxcZ4qxzzPjoNMDkSQfECKM/0`
`${ipfsGatewayUrl}QmUphf8LnNGdFwBevnxNkq8dxcZ4qxzzPjoNMDkSQfECKM/0`,
);
});
@@ -183,7 +183,7 @@ describe("IPFS Uploads", async () => {
},
];
const serialized = sampleObjects.map((o) =>
Buffer.from(JSON.stringify(o))
Buffer.from(JSON.stringify(o)),
);
const { baseUri: cid } = await storage.uploadBatch(serialized);
for (const object of sampleObjects) {
@@ -210,7 +210,7 @@ describe("IPFS Uploads", async () => {
(await getFile(`${cid}test.jpeg`)).headers
?.get("content-type")
?.toString() === "image/jpeg",
`${cid}`
`${cid}`,
);
});
@@ -223,7 +223,7 @@ describe("IPFS Uploads", async () => {
assert(
(await getFile(`${cid}2`)).headers?.get("content-type")?.toString() ===
"image/jpeg",
`${cid}`
`${cid}`,
);
});
it("should upload files according to start file number as 0", async () => {
@@ -235,7 +235,7 @@ describe("IPFS Uploads", async () => {
assert(
(await getFile(`${cid}0`)).headers?.get("content-type")?.toString() ===
"image/jpeg",
`${cid}`
`${cid}`,
);
});
it("should upload properties recursively in batch", async () => {
@@ -263,26 +263,26 @@ describe("IPFS Uploads", async () => {
},
];
const { baseUri, uris } = await storage.uploadMetadataBatch(
sampleObjects
sampleObjects,
);
assert(baseUri.startsWith("ipfs://") && baseUri.endsWith("/"));
assert(uris.length === sampleObjects.length);
const [metadata1, metadata2, metadata3] = await Promise.all(
(
await Promise.all(uris.map((m) => getFile(m)))
).map((m: any) => m.json())
).map((m: any) => m.json()),
);
assert(
metadata1.image ===
"ipfs://QmTpv5cWy677mgABsgJgwZ6pe2bEpSWQTvcCb8Hmj3ac8E/0"
"ipfs://QmTpv5cWy677mgABsgJgwZ6pe2bEpSWQTvcCb8Hmj3ac8E/0",
);
assert(
metadata2.image ===
"ipfs://QmTpv5cWy677mgABsgJgwZ6pe2bEpSWQTvcCb8Hmj3ac8E/1"
"ipfs://QmTpv5cWy677mgABsgJgwZ6pe2bEpSWQTvcCb8Hmj3ac8E/1",
);
assert(
metadata3.image ===
"ipfs://QmTpv5cWy677mgABsgJgwZ6pe2bEpSWQTvcCb8Hmj3ac8E/3"
"ipfs://QmTpv5cWy677mgABsgJgwZ6pe2bEpSWQTvcCb8Hmj3ac8E/3",
);
});
@@ -296,12 +296,12 @@ describe("IPFS Uploads", async () => {
sampleObjects.push(nft);
}
const { baseUri, uris } = await storage.uploadMetadataBatch(
sampleObjects
sampleObjects,
);
assert(baseUri.startsWith("ipfs://") && baseUri.endsWith("/"));
assert(uris.length === sampleObjects.length);
const metadatas = await Promise.all(
uris.map(async (m) => await storage.get(m))
uris.map(async (m) => await storage.get(m)),
);
for (let i = 0; i < metadatas.length; i++) {
const expected = sampleObjects[i];
@@ -327,7 +327,7 @@ describe("IPFS Uploads", async () => {
(await getFile(`${cid}TEST`)).headers
?.get("content-type")
?.toString() === "image/jpeg",
`${cid}`
`${cid}`,
);
});
+4 -1
View File
@@ -2,7 +2,7 @@
"$schema": "https://turborepo.org/schema.json",
"pipeline": {
"build": {
"outputs": ["dist/**", ".next/**"],
"outputs": ["dist/**"],
"dependsOn": ["^build"]
},
"sdk#build": {
@@ -13,6 +13,9 @@
"$contractPublisherAddress"
]
},
"auth#build": {
"outputs": ["dist/**", "express/**", "next/**"]
},
"test": {
"outputs": [],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*"],
+22 -58
View File
@@ -2395,17 +2395,17 @@
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.0.tgz#9f66664f9122ca555b96a5f2fc6e2af677bf801b"
integrity sha512-OI14ozFLThEV3ey6jE47zrzSTV/6eIMsvbwozo+XfdWqOPwQ7X00YkRx4GVMKMC0rM44oGS2gmwMKYpe4EblnA==
"@noble/ed25519@^1.6.1":
"@noble/ed25519@^1.6.1", "@noble/ed25519@^1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.0.tgz#583ac38340a479314b9e348d4572101ed9492f9d"
integrity sha512-LeAxFK0+181zQOhOUuKE8Jnd3duzYhDNd3iCLxpmzA5K+e4I1FdbrK3Ot0ZHBwZMeRD/6EojyUfTbpHZ+hkQHg==
"@noble/[email protected]", "@noble/hashes@~1.1.1":
"@noble/[email protected]", "@noble/hashes@^1.1.2", "@noble/hashes@~1.1.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183"
integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==
"@noble/[email protected]", "@noble/secp256k1@~1.6.0":
"@noble/[email protected]", "@noble/secp256k1@^1.6.3", "@noble/secp256k1@~1.6.0":
version "1.6.3"
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94"
integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==
@@ -2847,12 +2847,14 @@
tweetnacl "^1.0.3"
"@solana/web3.js@^1.31.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.35.1", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.44.0", "@solana/web3.js@^1.47.3", "@solana/web3.js@^1.50.1":
version "1.54.0"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.54.0.tgz#1124ea13a7006eac324a27b49c0c9924e3042476"
integrity sha512-Bz0OKYF5UM2vwY6eSTgBBSAVNOk5icyIXbviO99OvX0i2gmRlfd3rocTXRQWHK/tupZ7PBVd6Vux34qpeOr8Yw==
version "1.54.1"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.54.1.tgz#c39ffa598beaa6d761ab55c78263d874f4441e14"
integrity sha512-/PViPDGxF6oZZidcILndlm0MdbuzBouiQcqxrAfiBZ4lHMntLE4U75KhC+205EkVnkgCC4/prkjKVeSnbkfzrw==
dependencies:
"@babel/runtime" "^7.12.5"
"@ethersproject/sha2" "^5.5.0"
"@noble/ed25519" "^1.7.0"
"@noble/hashes" "^1.1.2"
"@noble/secp256k1" "^1.6.3"
"@solana/buffer-layout" "^4.0.0"
bigint-buffer "^1.1.5"
bn.js "^5.0.0"
@@ -2864,9 +2866,7 @@
js-sha3 "^0.8.0"
node-fetch "2"
rpc-websockets "^7.5.0"
secp256k1 "^4.0.2"
superstruct "^0.14.2"
tweetnacl "^1.0.3"
"@solidity-parser/parser@^0.14.1", "@solidity-parser/parser@^0.14.2":
version "0.14.3"
@@ -3026,7 +3026,7 @@
resolved "https://registry.yarnpkg.com/@thirdweb-dev/contracts/-/contracts-3.1.3.tgz#490b2a6c5e9d7fb25f46fed5fd1e6ee451546604"
integrity sha512-r00Bx0S5AaesJbeV5GrjdMcF/FillsQNL/6ai+d7XteW4WUz5vfjzoqfC0YasKtZBF4o4fw3l5Wyq+ZnuiqB/g==
"@trivago/prettier-plugin-sort-imports@^3.2.0", "@trivago/prettier-plugin-sort-imports@^3.3.0":
"@trivago/prettier-plugin-sort-imports@^3.3.0":
version "3.3.0"
resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-3.3.0.tgz#ee4e9ec1d8e3076b95fcb94311f42f7a61eecd37"
integrity sha512-1y44bVZuIN0RsS3oIiGd5k8Vm3IZXYZnp4VsP2Z/S5L9WAOw43HE2clso66M2S/dDeJ+8sKPqnHsEfh39Vjs3w==
@@ -3792,28 +3792,6 @@
dependencies:
"@walletconnect/window-getters" "^1.0.0"
"@web-std/blob@^3.0.3":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@web-std/blob/-/blob-3.0.4.tgz#dd67a685547331915428d69e723c7da2015c3fc5"
integrity sha512-+dibyiw+uHYK4dX5cJ7HA+gtDAaUUe6JsOryp2ZpAC7h4ICsh49E34JwHoEKPlPvP0llCrNzz45vvD+xX5QDBg==
dependencies:
"@web-std/stream" "1.0.0"
web-encoding "1.1.5"
"@web-std/file@^3.0.0", "@web-std/file@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@web-std/file/-/file-3.0.2.tgz#b84cc9ed754608b18dcf78ac62c40dbcc6a94692"
integrity sha512-pIH0uuZsmY8YFvSHP1NsBIiMT/1ce0suPrX74fEeO3Wbr1+rW0fUGEe4d0R99iLwXtyCwyserqCFI4BJkJlkRA==
dependencies:
"@web-std/blob" "^3.0.3"
"@web-std/[email protected]":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@web-std/stream/-/stream-1.0.0.tgz#01066f40f536e4329d9b696dc29872f3a14b93c1"
integrity sha512-jyIbdVl+0ZJyKGTV0Ohb9E6UnxP+t7ZzX4Do3AHjZKxUXKMs9EmqnBDQgHF7bEw0EzbQygOjtt/7gvtmi//iCQ==
dependencies:
web-streams-polyfill "^3.1.1"
"@yarnpkg/lockfile@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
@@ -3881,11 +3859,6 @@
dependencies:
csstype "3.1.0"
"@zxing/[email protected]":
version "0.9.0"
resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b"
integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==
JSONStream@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
@@ -4844,9 +4817,9 @@ [email protected]:
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
cac@^6.7.12:
version "6.7.12"
resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.12.tgz#6fb5ea2ff50bd01490dbda497f4ae75a99415193"
integrity sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA==
version "6.7.14"
resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959"
integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==
cacheable-lookup@^5.0.3:
version "5.0.4"
@@ -4909,9 +4882,9 @@ camelcase@^7.0.0:
integrity sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ==
caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001370:
version "1.0.30001383"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz#aecf317ccd940690725ae3ae4f28293c5fb8050e"
integrity sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==
version "1.0.30001384"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001384.tgz#029527c2d781a3cfef13fa63b3a78a6088e35973"
integrity sha512-BBWt57kqWbc0GYZXb47wTXpmAgqr5LSibPzNjk/AWMdmJMQhLqOl3c/Kd4OAU/tu4NLfYkMx8Tlq3RVBkOBolQ==
capability@^0.2.5:
version "0.2.5"
@@ -11945,7 +11918,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
util@^0.12.0, util@^0.12.3, util@^0.12.4:
util@^0.12.0, util@^0.12.4:
version "0.12.4"
resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==
@@ -12078,16 +12051,7 @@ wcwidth@^1.0.1:
dependencies:
defaults "^1.0.3"
web-[email protected]:
version "1.1.5"
resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864"
integrity sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==
dependencies:
util "^0.12.3"
optionalDependencies:
"@zxing/text-encoding" "0.9.0"
web-streams-polyfill@^3.0.3, web-streams-polyfill@^3.1.1:
web-streams-polyfill@^3.0.3:
version "3.2.1"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
@@ -12732,9 +12696,9 @@ yocto-queue@^0.1.0:
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
z-schema@~5.0.2:
version "5.0.3"
resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-5.0.3.tgz#68fafb9b735fc7f3c89eabb3e5a6353b4d7b4935"
integrity sha512-sGvEcBOTNum68x9jCpCVGPFJ6mWnkD0YxOcddDlJHRx3tKdB2q8pCHExMVZo/AV/6geuVJXG7hljDaWG8+5GDw==
version "5.0.4"
resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-5.0.4.tgz#ecad8bc5ef3283ae032d603286386cfb1380cce5"
integrity sha512-gm/lx3hDzJNcLwseIeQVm1UcwhWIKpSB4NqH89pTBtFns4k/HDHudsICtvG05Bvw/Mv3jMyk700y5dadueLHdA==
dependencies:
lodash.get "^4.4.2"
lodash.isequal "^4.5.0"
@@ -12742,7 +12706,7 @@ z-schema@~5.0.2:
optionalDependencies:
commander "^2.20.3"
zod@^3.11.6:
zod@^3.11.6, zod@^3.18.0:
version "3.18.0"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.18.0.tgz#2eed58b3cafb8d9a67aa2fee69279702f584f3bc"
integrity sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA==