feat: init

This commit is contained in:
keyp-dev
2024-11-12 17:39:43 +08:00
commit 231952d1c8
16 changed files with 4106 additions and 0 deletions

16
. swcrc Normal file
View File

@@ -0,0 +1,16 @@
{
"jsc": {
"target": "es2016",
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true
},
"transform": {
"decoratorMetadata": true
}
},
"module": {
"type": "commonjs"
}
}

60
.gitignore vendored Normal file
View File

@@ -0,0 +1,60 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
dist
tmp
/out-tsc
# dependencies
node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
# System Files
.DS_Store
Thumbs.db
credentials
.envrc.override
.nx-container
/packages/dev/database/bin/cli-hasura-**
logs
dbt
gifted-backend.iml
.react-email
.nx
.env.override
.env.**.override
.env.**.local
env/env.**.override
/tools/bin/cli_temporal*
/tools/bin/cli_nats_*
packages/apps/temporal-worker/src/assets/workflow.bundle
packages/apps/cli/_files

2
.tool-versions Normal file
View File

@@ -0,0 +1,2 @@
nodejs 21.7.3
pnpm 9.6.0

27
package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "create_gifted_box_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "swc-node src/index.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@swc/core": "^1.7.39",
"@types/memoizee": "^0.4.11",
"@types/node-fetch": "2",
"swc-node": "^1.0.0",
"typescript": "^5.6.3"
},
"dependencies": {
"@t3-oss/env-nextjs": "^0.8.0",
"memoizee": "^0.4.17",
"node-fetch": "2",
"simplehash-api": "^0.2.1",
"viem": "^2.21.35",
"zod": "^3.23.8"
}
}

845
pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1,845 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@t3-oss/env-nextjs':
specifier: ^0.8.0
version: 0.8.0(typescript@5.6.3)(zod@3.23.8)
memoizee:
specifier: ^0.4.17
version: 0.4.17
node-fetch:
specifier: '2'
version: 2.7.0
simplehash-api:
specifier: ^0.2.1
version: 0.2.1
viem:
specifier: ^2.21.35
version: 2.21.35(typescript@5.6.3)(zod@3.23.8)
zod:
specifier: ^3.23.8
version: 3.23.8
devDependencies:
'@swc/core':
specifier: ^1.7.39
version: 1.7.39
'@types/memoizee':
specifier: ^0.4.11
version: 0.4.11
'@types/node-fetch':
specifier: '2'
version: 2.6.11
swc-node:
specifier: ^1.0.0
version: 1.0.0(@swc/core@1.7.39)(@swc/types@0.1.13)(typescript@5.6.3)
typescript:
specifier: ^5.6.3
version: 5.6.3
packages:
'@adraffy/ens-normalize@1.11.0':
resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==}
'@emnapi/core@1.3.1':
resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==}
'@emnapi/runtime@1.3.1':
resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
'@emnapi/wasi-threads@1.0.1':
resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==}
'@napi-rs/wasm-runtime@0.2.5':
resolution: {integrity: sha512-kwUxR7J9WLutBbulqg1dfOrMTwhMdXLdcGUhcbCcGwnPLt3gz19uHVdwH1syKVDbE022ZS2vZxOWflFLS0YTjw==}
'@noble/curves@1.6.0':
resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==}
engines: {node: ^14.21.3 || >=16}
'@noble/hashes@1.5.0':
resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==}
engines: {node: ^14.21.3 || >=16}
'@oxc-resolver/binding-darwin-arm64@1.12.0':
resolution: {integrity: sha512-wYe+dlF8npM7cwopOOxbdNjtmJp17e/xF5c0K2WooQXy5VOh74icydM33+Uh/SZDgwyum09/U1FVCX5GdeQk+A==}
cpu: [arm64]
os: [darwin]
'@oxc-resolver/binding-darwin-x64@1.12.0':
resolution: {integrity: sha512-FZxxp99om+SlvBr1cjzF8A3TjYcS0BInCqjUlM+2f9m9bPTR2Bng9Zq5Q09ZQyrKJjfGKqlOEHs3akuVOnrx3Q==}
cpu: [x64]
os: [darwin]
'@oxc-resolver/binding-freebsd-x64@1.12.0':
resolution: {integrity: sha512-BZi0iU6IEOnXGSkqt1OjTTkN9wfyaK6kTpQwL/axl8eCcNDc7wbv1vloHgILf7ozAY1TP75nsLYlASYI4B5kGA==}
cpu: [x64]
os: [freebsd]
'@oxc-resolver/binding-linux-arm-gnueabihf@1.12.0':
resolution: {integrity: sha512-L2qnMEnZAqxbG9b1J3di/w/THIm+1fMVfbbTMWIQNMMXdMeqqDN6ojnOLDtuP564rAh4TBFPdLyEfGhMz6ipNA==}
cpu: [arm]
os: [linux]
'@oxc-resolver/binding-linux-arm64-gnu@1.12.0':
resolution: {integrity: sha512-otVbS4zeo3n71zgGLBYRTriDzc0zpruC0WI3ICwjpIk454cLwGV0yzh4jlGYWQJYJk0BRAmXFd3ooKIF+bKBHw==}
cpu: [arm64]
os: [linux]
'@oxc-resolver/binding-linux-arm64-musl@1.12.0':
resolution: {integrity: sha512-IStQDjIT7Lzmqg1i9wXvPL/NsYsxF24WqaQFS8b8rxra+z0VG7saBOsEnOaa4jcEY8MVpLYabFhTV+fSsA2vnA==}
cpu: [arm64]
os: [linux]
'@oxc-resolver/binding-linux-x64-gnu@1.12.0':
resolution: {integrity: sha512-SipT7EVORz8pOQSFwemOm91TpSiBAGmOjG830/o+aLEsvQ4pEy223+SAnCfITh7+AahldYsJnVoIs519jmIlKQ==}
cpu: [x64]
os: [linux]
'@oxc-resolver/binding-linux-x64-musl@1.12.0':
resolution: {integrity: sha512-mGh0XfUzKdn+WFaqPacziNraCWL5znkHRfQVxG9avGS9zb2KC/N1EBbPzFqutDwixGDP54r2gx4q54YCJEZ4iQ==}
cpu: [x64]
os: [linux]
'@oxc-resolver/binding-wasm32-wasi@1.12.0':
resolution: {integrity: sha512-SZN6v7apKmQf/Vwiqb6e/s3Y2Oacw8uW8V2i1AlxtyaEFvnFE0UBn89zq6swEwE3OCajNWs0yPvgAXUMddYc7Q==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
'@oxc-resolver/binding-win32-arm64-msvc@1.12.0':
resolution: {integrity: sha512-GRe4bqCfFsyghruEn5bv47s9w3EWBdO2q72xCz5kpQ0LWbw+enPHtTjw3qX5PUcFYpKykM55FaO0hFDs1yzatw==}
cpu: [arm64]
os: [win32]
'@oxc-resolver/binding-win32-x64-msvc@1.12.0':
resolution: {integrity: sha512-Z3llHH0jfJP4mlWq3DT7bK6qV+/vYe0+xzCgfc67+Tc/U3eYndujl880bexeGdGNPh87JeYznpZAOJ44N7QVVQ==}
cpu: [x64]
os: [win32]
'@scure/base@1.1.9':
resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==}
'@scure/bip32@1.5.0':
resolution: {integrity: sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==}
'@scure/bip39@1.4.0':
resolution: {integrity: sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==}
'@swc-node/core@1.13.3':
resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==}
engines: {node: '>= 10'}
peerDependencies:
'@swc/core': '>= 1.4.13'
'@swc/types': '>= 0.1'
'@swc-node/register@1.10.9':
resolution: {integrity: sha512-iXy2sjP0phPEpK2yivjRC3PAgoLaT4sjSk0LDWCTdcTBJmR4waEog0E6eJbvoOkLkOtWw37SB8vCkl/bbh4+8A==}
peerDependencies:
'@swc/core': '>= 1.4.13'
typescript: '>= 4.3'
'@swc-node/sourcemap-support@0.5.1':
resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==}
'@swc/core-darwin-arm64@1.7.39':
resolution: {integrity: sha512-o2nbEL6scMBMCTvY9OnbyVXtepLuNbdblV9oNJEFia5v5eGj9WMrnRQiylH3Wp/G2NYkW7V1/ZVW+kfvIeYe9A==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
'@swc/core-darwin-x64@1.7.39':
resolution: {integrity: sha512-qMlv3XPgtPi/Fe11VhiPDHSLiYYk2dFYl747oGsHZPq+6tIdDQjIhijXPcsUHIXYDyG7lNpODPL8cP/X1sc9MA==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
'@swc/core-linux-arm-gnueabihf@1.7.39':
resolution: {integrity: sha512-NP+JIkBs1ZKnpa3Lk2W1kBJMwHfNOxCUJXuTa2ckjFsuZ8OUu2gwdeLFkTHbR43dxGwH5UzSmuGocXeMowra/Q==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
'@swc/core-linux-arm64-gnu@1.7.39':
resolution: {integrity: sha512-cPc+/HehyHyHcvAsk3ML/9wYcpWVIWax3YBaA+ScecJpSE04l/oBHPfdqKUPslqZ+Gcw0OWnIBGJT/fBZW2ayw==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-arm64-musl@1.7.39':
resolution: {integrity: sha512-8RxgBC6ubFem66bk9XJ0vclu3exJ6eD7x7CwDhp5AD/tulZslTYXM7oNPjEtje3xxabXuj/bEUMNvHZhQRFdqA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-x64-gnu@1.7.39':
resolution: {integrity: sha512-3gtCPEJuXLQEolo9xsXtuPDocmXQx12vewEyFFSMSjOfakuPOBmOQMa0sVL8Wwius8C1eZVeD1fgk0omMqeC+Q==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-linux-x64-musl@1.7.39':
resolution: {integrity: sha512-mg39pW5x/eqqpZDdtjZJxrUvQNSvJF4O8wCl37fbuFUqOtXs4TxsjZ0aolt876HXxxhsQl7rS+N4KioEMSgTZw==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-win32-arm64-msvc@1.7.39':
resolution: {integrity: sha512-NZwuS0mNJowH3e9bMttr7B1fB8bW5svW/yyySigv9qmV5VcQRNz1kMlCvrCLYRsa93JnARuiaBI6FazSeG8mpA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
'@swc/core-win32-ia32-msvc@1.7.39':
resolution: {integrity: sha512-qFmvv5UExbJPXhhvCVDBnjK5Duqxr048dlVB6ZCgGzbRxuarOlawCzzLK4N172230pzlAWGLgn9CWl3+N6zfHA==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
'@swc/core-win32-x64-msvc@1.7.39':
resolution: {integrity: sha512-o+5IMqgOtj9+BEOp16atTfBgCogVak9svhBpwsbcJQp67bQbxGYhAPPDW/hZ2rpSSF7UdzbY9wudoX9G4trcuQ==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@swc/core@1.7.39':
resolution: {integrity: sha512-jns6VFeOT49uoTKLWIEfiQqJAlyqldNAt80kAr8f7a5YjX0zgnG3RBiLMpksx4Ka4SlK4O6TJ/lumIM3Trp82g==}
engines: {node: '>=10'}
peerDependencies:
'@swc/helpers': '*'
peerDependenciesMeta:
'@swc/helpers':
optional: true
'@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
'@swc/types@0.1.13':
resolution: {integrity: sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==}
'@t3-oss/env-core@0.8.0':
resolution: {integrity: sha512-Tc1pg0KH/tJeI0Z1s/Isp1VsGDj1N03ZAYFV8GjWgMxytF/ve0Dv+opjmTapHICRv8qiB1Y/fsTjkWNMpKPRCQ==}
peerDependencies:
typescript: '>=5.0.0'
zod: ^3.0.0
peerDependenciesMeta:
typescript:
optional: true
'@t3-oss/env-nextjs@0.8.0':
resolution: {integrity: sha512-bJyoE8of4QmqZN7a49iLJAbUq4graScb9ezXzvnuIVr9JP43C093vmy55hT1uZL533CwiPz8zo1INwyAS6qnHw==}
peerDependencies:
typescript: '>=5.0.0'
zod: ^3.0.0
peerDependenciesMeta:
typescript:
optional: true
'@tybys/wasm-util@0.9.0':
resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
'@types/memoizee@0.4.11':
resolution: {integrity: sha512-2gyorIBZu8GoDr9pYjROkxWWcFtHCquF7TVbN2I+/OvgZhnIGQS0vX5KJz4lXNKb8XOSfxFOSG5OLru1ESqLUg==}
'@types/node-fetch@2.6.11':
resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==}
'@types/node@22.7.9':
resolution: {integrity: sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==}
abitype@1.0.6:
resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==}
peerDependencies:
typescript: '>=5.0.4'
zod: ^3 >=3.22.0
peerDependenciesMeta:
typescript:
optional: true
zod:
optional: true
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
axios@1.7.7:
resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==}
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
d@1.0.2:
resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==}
engines: {node: '>=0.12'}
debug@4.3.7:
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
es5-ext@0.10.64:
resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==}
engines: {node: '>=0.10'}
es6-iterator@2.0.3:
resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==}
es6-symbol@3.1.4:
resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==}
engines: {node: '>=0.12'}
es6-weak-map@2.0.3:
resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==}
esniff@2.0.1:
resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==}
engines: {node: '>=0.10'}
event-emitter@0.3.5:
resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==}
ext@1.7.0:
resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
follow-redirects@1.15.9:
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
form-data@4.0.1:
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
engines: {node: '>= 6'}
is-promise@2.2.2:
resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==}
isows@1.0.6:
resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==}
peerDependencies:
ws: '*'
lru-queue@0.1.0:
resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==}
memoizee@0.4.17:
resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==}
engines: {node: '>=0.12'}
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
next-tick@1.1.0:
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
oxc-resolver@1.12.0:
resolution: {integrity: sha512-YlaCIArvWNKCWZFRrMjhh2l5jK80eXnpYP+bhRc1J/7cW3TiyEY0ngJo73o/5n8hA3+4yLdTmXLNTQ3Ncz50LQ==}
pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
simplehash-api@0.2.1:
resolution: {integrity: sha512-xhCXZN6fQy5EBinO/D3zd3I3szln1XWemUUNoXMerF6y7KojWNK6AoqXFe5zjJTXG6g7Vi4Jp58xwpeKOFbNCA==}
engines: {node: '>= 14.0.0'}
source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
swc-node@1.0.0:
resolution: {integrity: sha512-4+kibROq06E7Yj3kEcCRN1Ki2C/5i+5P1B7An9iS9PO1BQY5VzWFuLhV7y7xNxkZjc8FEaLCh97NGzs/XBfOMQ==}
hasBin: true
timers-ext@0.1.8:
resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==}
engines: {node: '>=0.12'}
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
tslib@2.8.0:
resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==}
type@2.7.3:
resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==}
typescript@5.6.3:
resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
engines: {node: '>=14.17'}
hasBin: true
undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
viem@2.21.35:
resolution: {integrity: sha512-f3EFc5JILeA9veuNymUN8HG/nKP9ykC0NCgwFrZWuxcCc822GaP0IEnkRBsHGqmjwbz//FxJFmvtx7TBcdVs0A==}
peerDependencies:
typescript: '>=5.0.4'
peerDependenciesMeta:
typescript:
optional: true
webauthn-p256@0.0.10:
resolution: {integrity: sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==}
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
ws@8.18.0:
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
zod@3.23.8:
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
snapshots:
'@adraffy/ens-normalize@1.11.0': {}
'@emnapi/core@1.3.1':
dependencies:
'@emnapi/wasi-threads': 1.0.1
tslib: 2.8.0
optional: true
'@emnapi/runtime@1.3.1':
dependencies:
tslib: 2.8.0
optional: true
'@emnapi/wasi-threads@1.0.1':
dependencies:
tslib: 2.8.0
optional: true
'@napi-rs/wasm-runtime@0.2.5':
dependencies:
'@emnapi/core': 1.3.1
'@emnapi/runtime': 1.3.1
'@tybys/wasm-util': 0.9.0
optional: true
'@noble/curves@1.6.0':
dependencies:
'@noble/hashes': 1.5.0
'@noble/hashes@1.5.0': {}
'@oxc-resolver/binding-darwin-arm64@1.12.0':
optional: true
'@oxc-resolver/binding-darwin-x64@1.12.0':
optional: true
'@oxc-resolver/binding-freebsd-x64@1.12.0':
optional: true
'@oxc-resolver/binding-linux-arm-gnueabihf@1.12.0':
optional: true
'@oxc-resolver/binding-linux-arm64-gnu@1.12.0':
optional: true
'@oxc-resolver/binding-linux-arm64-musl@1.12.0':
optional: true
'@oxc-resolver/binding-linux-x64-gnu@1.12.0':
optional: true
'@oxc-resolver/binding-linux-x64-musl@1.12.0':
optional: true
'@oxc-resolver/binding-wasm32-wasi@1.12.0':
dependencies:
'@napi-rs/wasm-runtime': 0.2.5
optional: true
'@oxc-resolver/binding-win32-arm64-msvc@1.12.0':
optional: true
'@oxc-resolver/binding-win32-x64-msvc@1.12.0':
optional: true
'@scure/base@1.1.9': {}
'@scure/bip32@1.5.0':
dependencies:
'@noble/curves': 1.6.0
'@noble/hashes': 1.5.0
'@scure/base': 1.1.9
'@scure/bip39@1.4.0':
dependencies:
'@noble/hashes': 1.5.0
'@scure/base': 1.1.9
'@swc-node/core@1.13.3(@swc/core@1.7.39)(@swc/types@0.1.13)':
dependencies:
'@swc/core': 1.7.39
'@swc/types': 0.1.13
'@swc-node/register@1.10.9(@swc/core@1.7.39)(@swc/types@0.1.13)(typescript@5.6.3)':
dependencies:
'@swc-node/core': 1.13.3(@swc/core@1.7.39)(@swc/types@0.1.13)
'@swc-node/sourcemap-support': 0.5.1
'@swc/core': 1.7.39
colorette: 2.0.20
debug: 4.3.7
oxc-resolver: 1.12.0
pirates: 4.0.6
tslib: 2.8.0
typescript: 5.6.3
transitivePeerDependencies:
- '@swc/types'
- supports-color
'@swc-node/sourcemap-support@0.5.1':
dependencies:
source-map-support: 0.5.21
tslib: 2.8.0
'@swc/core-darwin-arm64@1.7.39':
optional: true
'@swc/core-darwin-x64@1.7.39':
optional: true
'@swc/core-linux-arm-gnueabihf@1.7.39':
optional: true
'@swc/core-linux-arm64-gnu@1.7.39':
optional: true
'@swc/core-linux-arm64-musl@1.7.39':
optional: true
'@swc/core-linux-x64-gnu@1.7.39':
optional: true
'@swc/core-linux-x64-musl@1.7.39':
optional: true
'@swc/core-win32-arm64-msvc@1.7.39':
optional: true
'@swc/core-win32-ia32-msvc@1.7.39':
optional: true
'@swc/core-win32-x64-msvc@1.7.39':
optional: true
'@swc/core@1.7.39':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.13
optionalDependencies:
'@swc/core-darwin-arm64': 1.7.39
'@swc/core-darwin-x64': 1.7.39
'@swc/core-linux-arm-gnueabihf': 1.7.39
'@swc/core-linux-arm64-gnu': 1.7.39
'@swc/core-linux-arm64-musl': 1.7.39
'@swc/core-linux-x64-gnu': 1.7.39
'@swc/core-linux-x64-musl': 1.7.39
'@swc/core-win32-arm64-msvc': 1.7.39
'@swc/core-win32-ia32-msvc': 1.7.39
'@swc/core-win32-x64-msvc': 1.7.39
'@swc/counter@0.1.3': {}
'@swc/types@0.1.13':
dependencies:
'@swc/counter': 0.1.3
'@t3-oss/env-core@0.8.0(typescript@5.6.3)(zod@3.23.8)':
dependencies:
zod: 3.23.8
optionalDependencies:
typescript: 5.6.3
'@t3-oss/env-nextjs@0.8.0(typescript@5.6.3)(zod@3.23.8)':
dependencies:
'@t3-oss/env-core': 0.8.0(typescript@5.6.3)(zod@3.23.8)
zod: 3.23.8
optionalDependencies:
typescript: 5.6.3
'@tybys/wasm-util@0.9.0':
dependencies:
tslib: 2.8.0
optional: true
'@types/memoizee@0.4.11': {}
'@types/node-fetch@2.6.11':
dependencies:
'@types/node': 22.7.9
form-data: 4.0.1
'@types/node@22.7.9':
dependencies:
undici-types: 6.19.8
abitype@1.0.6(typescript@5.6.3)(zod@3.23.8):
optionalDependencies:
typescript: 5.6.3
zod: 3.23.8
asynckit@0.4.0: {}
axios@1.7.7:
dependencies:
follow-redirects: 1.15.9
form-data: 4.0.1
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
buffer-from@1.1.2: {}
colorette@2.0.20: {}
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
d@1.0.2:
dependencies:
es5-ext: 0.10.64
type: 2.7.3
debug@4.3.7:
dependencies:
ms: 2.1.3
delayed-stream@1.0.0: {}
es5-ext@0.10.64:
dependencies:
es6-iterator: 2.0.3
es6-symbol: 3.1.4
esniff: 2.0.1
next-tick: 1.1.0
es6-iterator@2.0.3:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
es6-symbol: 3.1.4
es6-symbol@3.1.4:
dependencies:
d: 1.0.2
ext: 1.7.0
es6-weak-map@2.0.3:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
es6-iterator: 2.0.3
es6-symbol: 3.1.4
esniff@2.0.1:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
event-emitter: 0.3.5
type: 2.7.3
event-emitter@0.3.5:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
ext@1.7.0:
dependencies:
type: 2.7.3
follow-redirects@1.15.9: {}
form-data@4.0.1:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
is-promise@2.2.2: {}
isows@1.0.6(ws@8.18.0):
dependencies:
ws: 8.18.0
lru-queue@0.1.0:
dependencies:
es5-ext: 0.10.64
memoizee@0.4.17:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
es6-weak-map: 2.0.3
event-emitter: 0.3.5
is-promise: 2.2.2
lru-queue: 0.1.0
next-tick: 1.1.0
timers-ext: 0.1.8
mime-db@1.52.0: {}
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
ms@2.1.3: {}
next-tick@1.1.0: {}
node-fetch@2.7.0:
dependencies:
whatwg-url: 5.0.0
oxc-resolver@1.12.0:
optionalDependencies:
'@oxc-resolver/binding-darwin-arm64': 1.12.0
'@oxc-resolver/binding-darwin-x64': 1.12.0
'@oxc-resolver/binding-freebsd-x64': 1.12.0
'@oxc-resolver/binding-linux-arm-gnueabihf': 1.12.0
'@oxc-resolver/binding-linux-arm64-gnu': 1.12.0
'@oxc-resolver/binding-linux-arm64-musl': 1.12.0
'@oxc-resolver/binding-linux-x64-gnu': 1.12.0
'@oxc-resolver/binding-linux-x64-musl': 1.12.0
'@oxc-resolver/binding-wasm32-wasi': 1.12.0
'@oxc-resolver/binding-win32-arm64-msvc': 1.12.0
'@oxc-resolver/binding-win32-x64-msvc': 1.12.0
pirates@4.0.6: {}
proxy-from-env@1.1.0: {}
simplehash-api@0.2.1:
dependencies:
axios: 1.7.7
transitivePeerDependencies:
- debug
source-map-support@0.5.21:
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
source-map@0.6.1: {}
swc-node@1.0.0(@swc/core@1.7.39)(@swc/types@0.1.13)(typescript@5.6.3):
dependencies:
'@swc-node/register': 1.10.9(@swc/core@1.7.39)(@swc/types@0.1.13)(typescript@5.6.3)
transitivePeerDependencies:
- '@swc/core'
- '@swc/types'
- supports-color
- typescript
timers-ext@0.1.8:
dependencies:
es5-ext: 0.10.64
next-tick: 1.1.0
tr46@0.0.3: {}
tslib@2.8.0: {}
type@2.7.3: {}
typescript@5.6.3: {}
undici-types@6.19.8: {}
viem@2.21.35(typescript@5.6.3)(zod@3.23.8):
dependencies:
'@adraffy/ens-normalize': 1.11.0
'@noble/curves': 1.6.0
'@noble/hashes': 1.5.0
'@scure/bip32': 1.5.0
'@scure/bip39': 1.4.0
abitype: 1.0.6(typescript@5.6.3)(zod@3.23.8)
isows: 1.0.6(ws@8.18.0)
webauthn-p256: 0.0.10
ws: 8.18.0
optionalDependencies:
typescript: 5.6.3
transitivePeerDependencies:
- bufferutil
- utf-8-validate
- zod
webauthn-p256@0.0.10:
dependencies:
'@noble/curves': 1.6.0
'@noble/hashes': 1.5.0
webidl-conversions@3.0.1: {}
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
ws@8.18.0: {}
zod@3.23.8: {}

492
src/abi/ERC1155.ts Normal file
View File

@@ -0,0 +1,492 @@
export const ERC1155 = {
abi: [
{
inputs: [],
stateMutability: 'nonpayable',
type: 'constructor',
},
{
inputs: [
{ internalType: 'address', name: 'sender', type: 'address' },
{
internalType: 'uint256',
name: 'balance',
type: 'uint256',
},
{ internalType: 'uint256', name: 'needed', type: 'uint256' },
{
internalType: 'uint256',
name: 'tokenId',
type: 'uint256',
},
],
name: 'ERC1155InsufficientBalance',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'approver', type: 'address' }],
name: 'ERC1155InvalidApprover',
type: 'error',
},
{
inputs: [
{ internalType: 'uint256', name: 'idsLength', type: 'uint256' },
{
internalType: 'uint256',
name: 'valuesLength',
type: 'uint256',
},
],
name: 'ERC1155InvalidArrayLength',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'operator', type: 'address' }],
name: 'ERC1155InvalidOperator',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }],
name: 'ERC1155InvalidReceiver',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'sender', type: 'address' }],
name: 'ERC1155InvalidSender',
type: 'error',
},
{
inputs: [
{ internalType: 'address', name: 'operator', type: 'address' },
{
internalType: 'address',
name: 'owner',
type: 'address',
},
],
name: 'ERC1155MissingApprovalForAll',
type: 'error',
},
{ inputs: [], name: 'EnforcedPause', type: 'error' },
{
inputs: [],
name: 'ExpectedPause',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'owner', type: 'address' }],
name: 'OwnableInvalidOwner',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
name: 'OwnableUnauthorizedAccount',
type: 'error',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'account',
type: 'address',
},
{
indexed: true,
internalType: 'address',
name: 'operator',
type: 'address',
},
{
indexed: false,
internalType: 'bool',
name: 'approved',
type: 'bool',
},
],
name: 'ApprovalForAll',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'previousOwner',
type: 'address',
},
{
indexed: true,
internalType: 'address',
name: 'newOwner',
type: 'address',
},
],
name: 'OwnershipTransferred',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'address',
name: 'account',
type: 'address',
},
],
name: 'Paused',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'operator',
type: 'address',
},
{
indexed: true,
internalType: 'address',
name: 'from',
type: 'address',
},
{ indexed: true, internalType: 'address', name: 'to', type: 'address' },
{
indexed: false,
internalType: 'uint256[]',
name: 'ids',
type: 'uint256[]',
},
{
indexed: false,
internalType: 'uint256[]',
name: 'values',
type: 'uint256[]',
},
],
name: 'TransferBatch',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'operator',
type: 'address',
},
{
indexed: true,
internalType: 'address',
name: 'from',
type: 'address',
},
{ indexed: true, internalType: 'address', name: 'to', type: 'address' },
{
indexed: false,
internalType: 'uint256',
name: 'id',
type: 'uint256',
},
{
indexed: false,
internalType: 'uint256',
name: 'value',
type: 'uint256',
},
],
name: 'TransferSingle',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'string',
name: 'value',
type: 'string',
},
{
indexed: true,
internalType: 'uint256',
name: 'id',
type: 'uint256',
},
],
name: 'URI',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'address',
name: 'account',
type: 'address',
},
],
name: 'Unpaused',
type: 'event',
},
{
inputs: [
{ internalType: 'address', name: 'account', type: 'address' },
{
internalType: 'uint256',
name: 'id',
type: 'uint256',
},
],
name: 'balanceOf',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address[]', name: 'accounts', type: 'address[]' },
{
internalType: 'uint256[]',
name: 'ids',
type: 'uint256[]',
},
],
name: 'balanceOfBatch',
outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'account', type: 'address' },
{
internalType: 'uint256',
name: 'id',
type: 'uint256',
},
{ internalType: 'uint256', name: 'value', type: 'uint256' },
],
name: 'burn',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'account', type: 'address' },
{
internalType: 'uint256[]',
name: 'ids',
type: 'uint256[]',
},
{ internalType: 'uint256[]', name: 'values', type: 'uint256[]' },
],
name: 'burnBatch',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'id', type: 'uint256' }],
name: 'exists',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'account', type: 'address' },
{
internalType: 'address',
name: 'operator',
type: 'address',
},
],
name: 'isApprovedForAll',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'account', type: 'address' },
{
internalType: 'uint256',
name: 'id',
type: 'uint256',
},
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
{
internalType: 'bytes',
name: 'data',
type: 'bytes',
},
],
name: 'mint',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'to', type: 'address' },
{
internalType: 'uint256[]',
name: 'ids',
type: 'uint256[]',
},
{ internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' },
{
internalType: 'bytes',
name: 'data',
type: 'bytes',
},
],
name: 'mintBatch',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [],
name: 'owner',
outputs: [{ internalType: 'address', name: '', type: 'address' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'pause',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [],
name: 'paused',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'renounceOwnership',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'from', type: 'address' },
{
internalType: 'address',
name: 'to',
type: 'address',
},
{ internalType: 'uint256[]', name: 'ids', type: 'uint256[]' },
{
internalType: 'uint256[]',
name: 'values',
type: 'uint256[]',
},
{ internalType: 'bytes', name: 'data', type: 'bytes' },
],
name: 'safeBatchTransferFrom',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'from', type: 'address' },
{
internalType: 'address',
name: 'to',
type: 'address',
},
{ internalType: 'uint256', name: 'id', type: 'uint256' },
{
internalType: 'uint256',
name: 'value',
type: 'uint256',
},
{ internalType: 'bytes', name: 'data', type: 'bytes' },
],
name: 'safeTransferFrom',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'operator', type: 'address' },
{
internalType: 'bool',
name: 'approved',
type: 'bool',
},
],
name: 'setApprovalForAll',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'string', name: 'newuri', type: 'string' }],
name: 'setURI',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }],
name: 'supportsInterface',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'totalSupply',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'id', type: 'uint256' }],
name: 'totalSupply',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }],
name: 'transferOwnership',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [],
name: 'unpause',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'id', type: 'uint256' }],
name: 'uri',
outputs: [{ internalType: 'string', name: '', type: 'string' }],
stateMutability: 'view',
type: 'function',
},
],
};

224
src/abi/ERC20.ts Normal file
View File

@@ -0,0 +1,224 @@
export const ERC20 = {
abi: [
{
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',
},
],
};

416
src/abi/ERC721.ts Normal file
View File

@@ -0,0 +1,416 @@
export const ERC721 = {
abi: [
{ inputs: [], stateMutability: 'nonpayable', type: 'constructor' },
{ inputs: [], name: 'ERC721EnumerableForbiddenBatchMint', type: 'error' },
{
inputs: [
{ internalType: 'address', name: 'sender', type: 'address' },
{ internalType: 'uint256', name: 'tokenId', type: 'uint256' },
{ internalType: 'address', name: 'owner', type: 'address' },
],
name: 'ERC721IncorrectOwner',
type: 'error',
},
{
inputs: [
{ internalType: 'address', name: 'operator', type: 'address' },
{ internalType: 'uint256', name: 'tokenId', type: 'uint256' },
],
name: 'ERC721InsufficientApproval',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'approver', type: 'address' }],
name: 'ERC721InvalidApprover',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'operator', type: 'address' }],
name: 'ERC721InvalidOperator',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'owner', type: 'address' }],
name: 'ERC721InvalidOwner',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }],
name: 'ERC721InvalidReceiver',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'sender', type: 'address' }],
name: 'ERC721InvalidSender',
type: 'error',
},
{
inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }],
name: 'ERC721NonexistentToken',
type: 'error',
},
{
inputs: [
{ internalType: 'address', name: 'owner', type: 'address' },
{ internalType: 'uint256', name: 'index', type: 'uint256' },
],
name: 'ERC721OutOfBoundsIndex',
type: 'error',
},
{ inputs: [], name: 'EnforcedPause', type: 'error' },
{ inputs: [], name: 'ExpectedPause', type: 'error' },
{
inputs: [{ internalType: 'address', name: 'owner', type: 'address' }],
name: 'OwnableInvalidOwner',
type: 'error',
},
{
inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
name: 'OwnableUnauthorizedAccount',
type: 'error',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'owner',
type: 'address',
},
{
indexed: true,
internalType: 'address',
name: 'approved',
type: 'address',
},
{
indexed: true,
internalType: 'uint256',
name: 'tokenId',
type: 'uint256',
},
],
name: 'Approval',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'owner',
type: 'address',
},
{
indexed: true,
internalType: 'address',
name: 'operator',
type: 'address',
},
{
indexed: false,
internalType: 'bool',
name: 'approved',
type: 'bool',
},
],
name: 'ApprovalForAll',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'uint256',
name: '_fromTokenId',
type: 'uint256',
},
{
indexed: false,
internalType: 'uint256',
name: '_toTokenId',
type: 'uint256',
},
],
name: 'BatchMetadataUpdate',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'uint256',
name: '_tokenId',
type: 'uint256',
},
],
name: 'MetadataUpdate',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'previousOwner',
type: 'address',
},
{
indexed: true,
internalType: 'address',
name: 'newOwner',
type: 'address',
},
],
name: 'OwnershipTransferred',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'address',
name: 'account',
type: 'address',
},
],
name: 'Paused',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'from',
type: 'address',
},
{ indexed: true, internalType: 'address', name: 'to', type: 'address' },
{
indexed: true,
internalType: 'uint256',
name: 'tokenId',
type: 'uint256',
},
],
name: 'Transfer',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'address',
name: 'account',
type: 'address',
},
],
name: 'Unpaused',
type: 'event',
},
{
inputs: [],
name: '__baseURI',
outputs: [{ internalType: 'string', name: '', type: 'string' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'to', type: 'address' },
{ internalType: 'uint256', name: 'tokenId', type: 'uint256' },
],
name: 'approve',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'address', name: 'owner', type: 'address' }],
name: 'balanceOf',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }],
name: 'burn',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }],
name: 'getApproved',
outputs: [{ internalType: 'address', name: '', type: 'address' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'owner', type: 'address' },
{ internalType: 'address', name: 'operator', type: 'address' },
],
name: 'isApprovedForAll',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'name',
outputs: [{ internalType: 'string', name: '', type: 'string' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'owner',
outputs: [{ internalType: 'address', name: '', type: 'address' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }],
name: 'ownerOf',
outputs: [{ internalType: 'address', name: '', type: 'address' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'paused',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'renounceOwnership',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'to', type: 'address' },
{ internalType: 'string', name: 'uri', type: 'string' },
],
name: 'safeMint',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'from', type: 'address' },
{ internalType: 'address', name: 'to', type: 'address' },
{ internalType: 'uint256', name: 'tokenId', type: 'uint256' },
],
name: 'safeTransferFrom',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'from', type: 'address' },
{ internalType: 'address', name: 'to', type: 'address' },
{ internalType: 'uint256', name: 'tokenId', type: 'uint256' },
{ internalType: 'bytes', name: 'data', type: 'bytes' },
],
name: 'safeTransferFrom',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'operator', type: 'address' },
{ internalType: 'bool', name: 'approved', type: 'bool' },
],
name: 'setApprovalForAll',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'string', name: 'baseURI', type: 'string' }],
name: 'setBaseURI',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }],
name: 'supportsInterface',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'symbol',
outputs: [{ internalType: 'string', name: '', type: 'string' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }],
name: 'tokenByIndex',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'owner', type: 'address' },
{ internalType: 'uint256', name: 'index', type: 'uint256' },
],
name: 'tokenOfOwnerByIndex',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }],
name: 'tokenURI',
outputs: [{ internalType: 'string', name: '', type: 'string' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'totalSupply',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{ internalType: 'address', name: 'from', type: 'address' },
{ internalType: 'address', name: 'to', type: 'address' },
{ internalType: 'uint256', name: 'tokenId', type: 'uint256' },
],
name: 'transferFrom',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }],
name: 'transferOwnership',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
],
};

1388
src/abi/GiftedBox.ts Normal file

File diff suppressed because it is too large Load Diff

64
src/contract.interface.ts Normal file
View File

@@ -0,0 +1,64 @@
import { Chain } from "viem";
import {
arbitrum,
arbitrumSepolia,
base,
baseSepolia,
mainnet,
sepolia,
} from "viem/chains";
import { z } from "zod";
export const EVMChainNameSchema = z.enum([
"ethereum",
"sepolia",
"base",
"base_sepolia",
"arbitrum",
"arbitrum_sepolia",
]);
export type EVMChainName = z.infer<typeof EVMChainNameSchema>;
export const EVMChainMap: { [key in EVMChainName]: Chain } = {
ethereum: mainnet,
sepolia: sepolia,
base: base,
base_sepolia: baseSepolia,
arbitrum: arbitrum,
arbitrum_sepolia: arbitrumSepolia,
};
const EVMChainConfigSchema = z.object({
private_key: z.string(),
unified_store_address: z.string(),
});
export type EVMChainConfig = z.infer<typeof EVMChainConfigSchema>;
export const MintGiftBoxSchema = z.object({
sender: z.string(),
recipient: z.string(),
});
export type MintGiftBox = z.infer<typeof MintGiftBoxSchema>;
export const EVMTokenTypeSchema = z.enum([
"GAS_TOKEN",
"ERC20",
"ERC721",
"ERC1155",
]);
export type EVMTokenType = z.infer<typeof EVMTokenTypeSchema>;
export const TransferTokenToGiftBoxSchema = z.object({
token_contract_address: z.string(),
token_id: z.string(),
amount: z.number().optional(),
type: EVMTokenTypeSchema,
gift_token_id: z.string(),
});
export type TransferTokenToGiftBox = z.infer<
typeof TransferTokenToGiftBoxSchema
>;

248
src/contract.ts Normal file
View File

@@ -0,0 +1,248 @@
import {
Address,
createPublicClient,
createWalletClient,
decodeEventLog,
getAddress,
http,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import {
EVMChainMap,
EVMChainName,
MintGiftBox,
TransferTokenToGiftBox,
} from "./contract.interface";
import { env } from "./env";
import fetch from "node-fetch";
import memoizee from "memoizee";
import { giftedBox } from "./abi/GiftedBox";
import { ERC721 } from "./abi/ERC721";
import { ERC1155 } from "./abi/ERC1155";
export class Contract {
chain_name: EVMChainName;
private_key: string;
rpc_url?: string;
constructor(chain_name: EVMChainName, private_key: string, rpc_url?: string) {
this.chain_name = chain_name;
this.private_key = private_key;
this.rpc_url = rpc_url;
}
getPublicClient() {
return createPublicClient({
chain: EVMChainMap[this.chain_name],
transport: this.rpc_url ? http(this.rpc_url) : http(),
});
}
getWalletClient() {
return createWalletClient({
chain: EVMChainMap[this.chain_name],
account: privateKeyToAccount(`0x${this.private_key}`),
transport: this.rpc_url ? http(this.rpc_url) : http(),
});
}
getGiftedContractAddresses = memoizee(
async () => {
const res = await fetch(`${env().api_url}/api/v1/contracts/addresses`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"x-api-key": env().api_key,
},
});
const data = await res.json();
return data as {
UnifiedStore: string;
GiftedAccountGuardian: string;
GiftedAccount: string;
GiftedBox: string;
ERC6551Registry: string;
Vault: string;
GasSponsorBook: string;
};
},
{
promise: true,
maxAge: 24 * 60 * 60 * 1000,
}
);
private async simulateMintGiftBox({ sender, recipient }: MintGiftBox) {
const publicClient = this.getPublicClient();
const account = this.getWalletClient().account;
const { GiftedBox } = await this.getGiftedContractAddresses();
try {
const operator = account.address;
const { request } = await publicClient.simulateContract({
account,
address: GiftedBox as Address,
abi: giftedBox.abi,
functionName: "sendGift",
args: [sender as Address, recipient as Address, operator as Address],
});
return { request };
} catch (error) {
throw new Error(`EVM SimulateMintGiftBox: ${error}`);
}
}
async mintGiftBox(data: MintGiftBox): Promise<string> {
const request = await this.simulateMintGiftBox(data);
const walletClient = this.getWalletClient();
try {
const transaction_hash = await walletClient.writeContract(request as any);
return transaction_hash;
} catch (error) {
throw new Error(`EVM MintGiftBox: ${error}`);
}
}
async waitForTransactionReceipt(hash: string) {
const publicClient = this.getPublicClient();
const res = await publicClient.waitForTransactionReceipt({
hash: hash as Address,
});
if (res.status === "reverted") {
throw new Error(`Transaction reverted: ${hash}`);
}
}
async getGiftBoxTokenByHash(hash: string): Promise<string> {
const publicClient = this.getPublicClient();
const { GiftedBox } = await this.getGiftedContractAddresses();
const transaction = await publicClient.waitForTransactionReceipt({
hash: hash as Address,
});
if (!transaction.to || getAddress(transaction.to) !== GiftedBox) {
throw new Error(
`Transaction to ${transaction.to}, expected ${GiftedBox}`
);
}
const logs = transaction.logs;
const [transferLog] = logs;
if (transferLog == null) {
throw new Error(`NoTransferLogFoundError: ${hash}`);
}
const { args } = decodeEventLog({
abi: giftedBox.abi,
eventName: "GiftedBoxSentToVault",
data: transferLog.data,
topics: transferLog.topics,
});
if (args == null || args.tokenId == null) {
throw new Error(`tokenId not found in ${hash}`);
}
return args.tokenId.toString();
}
private async simulateTransferTokenToGiftBox({
token_id,
amount,
token_contract_address,
type,
gift_token_id,
}: TransferTokenToGiftBox) {
const publicClient = this.getPublicClient();
const account = this.getWalletClient().account;
const { GiftedBox } = await this.getGiftedContractAddresses();
const token_account_address = await publicClient.readContract({
address: GiftedBox as Address,
abi: giftedBox.abi,
functionName: "tokenAccountAddress",
args: [BigInt(gift_token_id)],
});
try {
const request = await (async () => {
switch (type) {
case "ERC721": {
const { request } = await publicClient.simulateContract({
account,
address: token_contract_address as Address,
abi: ERC721.abi,
functionName: "safeTransferFrom",
args: [account.address, token_account_address, token_id],
});
return request;
}
case "ERC1155": {
if (amount == null) {
throw new Error(`InvalidAmount: ${amount}`);
}
const { request } = await publicClient.simulateContract({
account,
address: token_contract_address as Address,
abi: ERC1155.abi,
functionName: "safeTransferFrom",
args: [
account.address,
token_account_address,
token_id,
BigInt(amount),
"0x",
],
});
return request;
}
default:
throw new Error(`InvalidTokenType: ${type}`);
}
})();
return request;
} catch (error) {
throw new Error(`EVM SimulateTransferTokenToGiftBox : ${error}`);
}
}
async transferTokenToGiftBox(data: TransferTokenToGiftBox): Promise<string> {
const publicClient = this.getPublicClient();
const account = this.getWalletClient().account;
const { GiftedBox } = await this.getGiftedContractAddresses();
const token_account_address = await publicClient.readContract({
address: GiftedBox as Address,
abi: giftedBox.abi,
functionName: "tokenAccountAddress",
args: [BigInt(data.gift_token_id)],
});
const request = await this.simulateTransferTokenToGiftBox(data);
const walletClient = this.getWalletClient();
try {
const transaction_hash = await walletClient.writeContract(request as any);
return transaction_hash;
} catch (error) {
throw new Error(`EVM TransferTokenToGiftBox: ${error}`);
}
}
}

14
src/env.ts Normal file
View File

@@ -0,0 +1,14 @@
import { createEnv } from "@t3-oss/env-nextjs";
import memoizee from "memoizee";
import { z } from "zod";
export const env = memoizee(() =>
createEnv({
server: {
api_url: z.string().default("https://rest-api-staging.gifted.art"),
api_key: z.string(),
private_key: z.string(),
},
runtimeEnv: process.env as any,
})
);

94
src/evm.ts Normal file
View File

@@ -0,0 +1,94 @@
import { ArtworkNFT, NFT } from "./types";
import { Chain as simplehashChain, createApi } from "simplehash-api";
import { isAddressEqual } from "viem";
import { EVMChainName } from "./contract.interface";
const convertIpfsMediaUrl = (url: string) => {
if (url.startsWith("ipfs://ipfs/")) {
const cid = url.split("ipfs://ipfs/").pop();
return `https://ipfs-gateway.myfilebase.com/ipfs/${cid}`;
} else if (url.startsWith("ipfs://")) {
const cid = url.split("ipfs://").pop();
return `https://ipfs-gateway.myfilebase.com/ipfs/${cid}`;
}
return url;
};
function parseEVMNFT(nft: NFT): ArtworkNFT {
const {
image_url,
video_url,
image_properties,
video_properties,
extra_metadata,
contract,
} = nft;
const normalizedImageUrl = image_url
? convertIpfsMediaUrl(image_url)
: image_url;
const resultVideoUrl = video_url ?? extra_metadata?.animation_original_url;
const normalizedAnimationUrl = resultVideoUrl
? convertIpfsMediaUrl(resultVideoUrl)
: resultVideoUrl;
const posterUrl = normalizedAnimationUrl ? normalizedImageUrl : undefined;
const mediaUrl = normalizedAnimationUrl || normalizedImageUrl;
const properties = resultVideoUrl ? video_properties : image_properties;
return {
type: contract.type,
token_id: nft.token_id,
contract: nft.contract_address,
image: normalizedImageUrl,
animation_url: normalizedAnimationUrl,
mediaUrl,
posterUrl,
mediaMetadata: {
...properties,
width: properties?.width ?? 0,
height: properties?.height ?? 0,
posterUrl,
contentType: properties?.mime_type ?? "text/html",
},
};
}
const simpleHash = createApi("keyp_sk_dzqyfx79zfvsjn0jv8ayoay0kh3bf91r");
const EVMChainMapToSimpleHashChain: { [key in EVMChainName]: simplehashChain } =
{
ethereum: "ethereum",
sepolia: "ethereum-sepolia",
base: "base",
// @ts-ignore
base_sepolia: "base-sepolia",
arbitrum: "arbitrum",
// @ts-ignore
arbitrum_sepolia: "arbitrum-sepolia",
};
export async function getNFTsByOwner({
chain,
owner,
contract,
token_id,
}: {
chain: EVMChainName;
owner: string;
contract: string;
token_id?: string;
}) {
const nfts = await simpleHash.nftsByOwners(
[EVMChainMapToSimpleHashChain[chain]],
[owner]
);
return nfts
.filter((nft) =>
isAddressEqual(nft.contract_address as any, contract as any)
)
.filter((nft) => (token_id ? nft.token_id === token_id : true))
.map((nft) => parseEVMNFT(nft as any));
}

154
src/index.ts Normal file
View File

@@ -0,0 +1,154 @@
import fetch from "node-fetch";
import { getNFTsByOwner } from "./evm";
import { ArtworkNFT } from "./types";
import { env } from "./env";
import { EVMChainName } from "./contract.interface";
import { Contract } from "./contract";
const getUserInfo = async () => {
const res = await fetch(`${env().api_url}/api/v1/auth/me`, {
headers: {
"x-api-key": env().api_key,
},
});
return (await res.json()) as {
chain_name: EVMChainName;
address: string;
};
};
const getAddressByEmail = async (email: string) => {
const res = await fetch(`${env().api_url}/api/v1/auth/address`, {
body: JSON.stringify({ email }),
});
return (await res.json()) as {
address: string;
};
};
// Function to create a gift box
const createGiftBoxTask = async (
recipient: {
email: string;
first_name: string;
last_name: string;
},
artwork_nft: ArtworkNFT
) => {
const res = await fetch(`${env().api_url}/api/v1/tasks/ready`, {
method: "POST",
headers: {
"Content-Type": "application/json",
// Using staging environment API key, if you want to use prod environment, you need to use prod API key
"x-api-key": env().api_key,
},
body: JSON.stringify([
{
args: {
recipient,
artworks: [
{
// NFT-related information
nft_contract: artwork_nft.contract,
token_id: artwork_nft.token_id,
source: artwork_nft.mediaUrl,
source_metadata: artwork_nft.mediaMetadata,
minted_on: new Date().toISOString(),
// Artist and artwork information
artist_name: "Annibale Siconolfi",
artist_description: "",
artist_avatar:
"https://ipfs.pixura.io/ipfs/QmaQhxcVm8GeCK9355qBxpEERXNe5avaLHbZwGnY3vhHJq/hidden%20city.jpg",
artwork_name: "Demo Artwork name",
artwork_description: "Demo Artwork description",
type: artwork_nft.type,
// Only support 1, indicating one 1155/721 NFT
amount: 1,
},
],
// Gift box configuration
gift_box: {
// Text display for corresponding positions on the page
note_subject: "To test",
message: "Thank you for joining Gifted.art",
message_bless: " ",
signature: "—Gifted.art Team",
// UI-related configurations for the page
// Wrapping animation, if you need more, please go to https://app.gifted.art/, follow the process to send a gift, and you can see more wrapping styles at the last step
wrapping: "Silver Elegance",
},
},
},
]),
});
if (!res.ok) {
const data = await res.json();
console.error(res.statusText);
console.error(JSON.stringify(data, null, 2));
return;
}
// return task id
console.log(await res.text());
};
const main = async () => {
const user = await getUserInfo();
const contract = new Contract(user.chain_name, env().private_key);
const account = contract.getWalletClient().account;
// We fetched a random NFT from NFTVault here. You should mint and send your NFT into NFVault and then call gifteds API to have it sent out.
const nfts = await getNFTsByOwner({
chain: user.chain_name,
owner: account.address,
// base-sepolia 1155 contract address (if you want to send 721 NFT, you need to use the 721 contract address)
contract: "0x2Faa4ff5Ee8D3D47915ABe87Ae44f550448A4CB0",
});
if (nfts.length === 0) {
console.error("No NFTs found");
return;
}
const nft = nfts[0];
const recipient = {
email: "test1@keyp.dev",
first_name: "keyp",
last_name: "test",
};
const recipientAddress = (await getAddressByEmail(recipient.email)).address;
const mint_gift_box_transaction_hash = await contract.mintGiftBox({
sender: user.address,
recipient: recipientAddress,
});
await contract.waitForTransactionReceipt(mint_gift_box_transaction_hash);
const gift_token_id = await contract.getGiftBoxTokenByHash(
mint_gift_box_transaction_hash
);
const transfer_transaction_hash = await contract.transferTokenToGiftBox({
token_contract_address: nft.contract,
token_id: nft.token_id,
type: nft.type,
gift_token_id: gift_token_id,
});
await contract.waitForTransactionReceipt(transfer_transaction_hash);
await createGiftBoxTask(recipient, nft);
};
// Execute the main function and catch any errors
main().catch(console.error);

51
src/types.ts Normal file
View File

@@ -0,0 +1,51 @@
export enum EVMNftTokenType {
ERC721 = "ERC721",
ERC1155 = "ERC1155",
}
export type ArtworkNFT = {
contract: string;
type: EVMNftTokenType;
token_id: string;
image: string;
animation_url?: string;
mediaUrl: string;
posterUrl?: string;
mediaMetadata: {
width: number;
height: number;
contentType: string;
posterUrl?: string;
};
};
interface Owner {
owner_address: string;
quantity: number;
quantity_string: string;
}
interface Contract {
type: EVMNftTokenType;
}
export type Properties = {
height: number;
mime_type: string;
width: number;
};
export type NFT = {
name: string;
description: string;
contract_address: string;
token_id: string;
image_url: string;
video_url: string;
contract: Contract;
owners: Owner[];
image_properties: Properties | null;
video_properties: Properties | null;
extra_metadata: {
animation_original_url?: string;
};
};

11
tsconfig.json Normal file
View File

@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": ["src"]
}