Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ba3e9db97 |
+5
-6
@@ -1,11 +1,10 @@
|
|||||||
# Client-side environment variables must be prefixed with NEXT_PUBLIC_
|
# Client-side environment variables must be prefixed with NEXT_PUBLIC_
|
||||||
|
|
||||||
# Solana Payment Configuration
|
# Solana Payment Configuration
|
||||||
# Run the solana proxy to setup RPC and WS URLs: https://git.vdb.to/LaconicNetwork/solana-proxy
|
# TODO: Use different RPC URL
|
||||||
NEXT_PUBLIC_SOLANA_RPC_URL=
|
NEXT_PUBLIC_SOLANA_RPC_URL=https://skilled-prettiest-seed.solana-mainnet.quiknode.pro/eeecfebd04e345f69f1900cc3483cbbfea02a158
|
||||||
NEXT_PUBLIC_SOLANA_WS_URL=
|
NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS=97RggLo3zV5kFGYW4yoQTxr4Xkz4Vg2WPHzNYXXWpump
|
||||||
NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS=71Jvq4Epe2FCJ7JFSF7jLXdNk1Wy4Bhqd9iL6bEFELvg
|
NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL=MTM
|
||||||
NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL=GOR
|
|
||||||
|
|
||||||
# Gorbagana Chain Configuration
|
# Gorbagana Chain Configuration
|
||||||
NEXT_PUBLIC_GORBAGANA_RPC_URL=https://rpc.gorbagana.wtf
|
NEXT_PUBLIC_GORBAGANA_RPC_URL=https://rpc.gorbagana.wtf
|
||||||
@@ -24,8 +23,8 @@ NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT=https://laconicd-mainnet-1.laconic.com/graphql
|
|||||||
NEXT_PUBLIC_ALNT_COST_LRN=lrn://laconic/pricing/alnt
|
NEXT_PUBLIC_ALNT_COST_LRN=lrn://laconic/pricing/alnt
|
||||||
NEXT_PUBLIC_DEPLOYMENT_COST_LRN=lrn://laconic/pricing/webapp-deployment
|
NEXT_PUBLIC_DEPLOYMENT_COST_LRN=lrn://laconic/pricing/webapp-deployment
|
||||||
REGISTRY_GAS_PRICE=0.001
|
REGISTRY_GAS_PRICE=0.001
|
||||||
REGISTRY_AUTHORITY=laconic-deploy
|
|
||||||
REGISTRY_BOND_ID=5d82586d156fb6671a9170d92f930a72a49a29afb45e30e16fff2100e30776e2
|
REGISTRY_BOND_ID=5d82586d156fb6671a9170d92f930a72a49a29afb45e30e16fff2100e30776e2
|
||||||
|
REGISTRY_AUTHORITY=laconic-deploy
|
||||||
REGISTRY_USER_KEY=
|
REGISTRY_USER_KEY=
|
||||||
|
|
||||||
# Application Configuration
|
# Application Configuration
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ Required environment variables:
|
|||||||
|
|
||||||
Client-side (must be prefixed with NEXT_PUBLIC_):
|
Client-side (must be prefixed with NEXT_PUBLIC_):
|
||||||
- `NEXT_PUBLIC_SOLANA_RPC_URL` - The RPC URL for the Solana blockchain (SPL token transactions)
|
- `NEXT_PUBLIC_SOLANA_RPC_URL` - The RPC URL for the Solana blockchain (SPL token transactions)
|
||||||
- `NEXT_PUBLIC_SOLANA_WS_URL` - The WS URL for the Solana blockchain (SPL token transactions)
|
|
||||||
- `NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS` - The mint address of the SPL token to accept
|
- `NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS` - The mint address of the SPL token to accept
|
||||||
- `NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL` - The token symbol to display (e.g., "GOR")
|
- `NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL` - The token symbol to display (e.g., "GOR")
|
||||||
- `NEXT_PUBLIC_GORBAGANA_RPC_URL` - The RPC URL for the Gorbagana blockchain (native GOR transactions)
|
- `NEXT_PUBLIC_GORBAGANA_RPC_URL` - The RPC URL for the Gorbagana blockchain (native GOR transactions)
|
||||||
|
|||||||
+2
-2
@@ -55,7 +55,7 @@
|
|||||||
- Add configuration for the app:
|
- Add configuration for the app:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -s https://git.vdb.to/LaconicNetwork/gor-deploy/raw/branch/main/.env.example -o .app.env
|
curl -s https://git.vdb.to/LaconicNetwork/gor-deploy/raw/branch/mtm-deploy/.env.example -o .app.env
|
||||||
|
|
||||||
# Fill in the required values
|
# Fill in the required values
|
||||||
nano .app.env
|
nano .app.env
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
# In gor-deploy/deploy dir
|
# In gor-deploy/deploy dir
|
||||||
docker run -it \
|
docker run -it \
|
||||||
-v ./:/app/deploy -w /app/deploy \
|
-v ./:/app/deploy -w /app/deploy \
|
||||||
-e DEPLOYMENT_DNS=gor-deploy.laconic.com \
|
-e DEPLOYMENT_DNS=mtm-deploy.laconic.com \
|
||||||
cerc/laconic-registry-cli:latest \
|
cerc/laconic-registry-cli:latest \
|
||||||
./deploy.sh
|
./deploy.sh
|
||||||
```
|
```
|
||||||
|
|||||||
+2
-2
@@ -12,12 +12,12 @@ echo "Using AUTHORITY: $AUTHORITY"
|
|||||||
REPO_URL="https://git.vdb.to/LaconicNetwork/gor-deploy"
|
REPO_URL="https://git.vdb.to/LaconicNetwork/gor-deploy"
|
||||||
|
|
||||||
# Get the latest commit hash for a branch
|
# Get the latest commit hash for a branch
|
||||||
BRANCH_NAME="main"
|
BRANCH_NAME="mtm-deploy"
|
||||||
LATEST_HASH=$(git ls-remote $REPO_URL refs/heads/$BRANCH_NAME | awk '{print $1}')
|
LATEST_HASH=$(git ls-remote $REPO_URL refs/heads/$BRANCH_NAME | awk '{print $1}')
|
||||||
|
|
||||||
PACKAGE_VERSION=$(curl -s $REPO_URL/raw/branch/$BRANCH_NAME/package.json | jq -r .version)
|
PACKAGE_VERSION=$(curl -s $REPO_URL/raw/branch/$BRANCH_NAME/package.json | jq -r .version)
|
||||||
|
|
||||||
APP_NAME=gor-deploy
|
APP_NAME=mtm-deploy
|
||||||
|
|
||||||
echo "Repo: ${REPO_URL}"
|
echo "Repo: ${REPO_URL}"
|
||||||
echo "Latest hash: ${LATEST_HASH}"
|
echo "Latest hash: ${LATEST_HASH}"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
record:
|
record:
|
||||||
type: ApplicationRecord
|
type: ApplicationRecord
|
||||||
version: 0.0.4
|
version: 0.0.3
|
||||||
repository_ref: bc0d10d4c38d2d20de88ac8352ab8571bbbffef4
|
repository_ref: 169c992abfca6994f78ba1b37049f47d33451040
|
||||||
repository: ["https://git.vdb.to/LaconicNetwork/gor-deploy"]
|
repository: ["https://git.vdb.to/LaconicNetwork/gor-deploy"]
|
||||||
app_type: webapp
|
app_type: webapp
|
||||||
name: gor-deploy
|
name: mtm-deploy
|
||||||
app_version: 0.1.0
|
app_version: 0.1.0
|
||||||
|
|||||||
Generated
+8
-243
@@ -516,74 +516,6 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/template": {
|
|
||||||
"version": "7.27.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
|
||||||
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.27.1",
|
|
||||||
"@babel/parser": "^7.27.2",
|
|
||||||
"@babel/types": "^7.27.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/traverse": {
|
|
||||||
"version": "7.28.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz",
|
|
||||||
"integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.27.1",
|
|
||||||
"@babel/generator": "^7.28.0",
|
|
||||||
"@babel/helper-globals": "^7.28.0",
|
|
||||||
"@babel/parser": "^7.28.0",
|
|
||||||
"@babel/template": "^7.27.2",
|
|
||||||
"@babel/types": "^7.28.0",
|
|
||||||
"debug": "^4.3.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/traverse--for-generate-function-map": {
|
|
||||||
"name": "@babel/traverse",
|
|
||||||
"version": "7.28.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz",
|
|
||||||
"integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.27.1",
|
|
||||||
"@babel/generator": "^7.28.0",
|
|
||||||
"@babel/helper-globals": "^7.28.0",
|
|
||||||
"@babel/parser": "^7.28.0",
|
|
||||||
"@babel/template": "^7.27.2",
|
|
||||||
"@babel/types": "^7.28.0",
|
|
||||||
"debug": "^4.3.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/types": {
|
|
||||||
"version": "7.28.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
|
|
||||||
"integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/helper-string-parser": "^7.27.1",
|
|
||||||
"@babel/helper-validator-identifier": "^7.27.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@cerc-io/laconic-registry-cli": {
|
"node_modules/@cerc-io/laconic-registry-cli": {
|
||||||
"version": "0.2.10",
|
"version": "0.2.10",
|
||||||
"resolved": "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Flaconic-registry-cli/-/0.2.10/laconic-registry-cli-0.2.10.tgz",
|
"resolved": "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Flaconic-registry-cli/-/0.2.10/laconic-registry-cli-0.2.10.tgz",
|
||||||
@@ -5220,17 +5152,11 @@
|
|||||||
"url": "https://github.com/sponsors/epoberezkin"
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/anser": {
|
|
||||||
"version": "1.4.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz",
|
|
||||||
"integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -6842,18 +6768,12 @@
|
|||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/escape-html": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
@@ -7685,16 +7605,6 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fresh": {
|
|
||||||
"version": "0.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
|
||||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fs-extra": {
|
"node_modules/fs-extra": {
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
@@ -7767,20 +7677,11 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/gensync": {
|
|
||||||
"version": "1.0.0-beta.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
|
||||||
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/get-caller-file": {
|
"node_modules/get-caller-file": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "6.* || 8.* || >= 10.*"
|
"node": "6.* || 8.* || >= 10.*"
|
||||||
@@ -8442,6 +8343,7 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -10892,124 +10794,6 @@
|
|||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qrcode/node_modules/cliui": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"string-width": "^4.2.0",
|
|
||||||
"strip-ansi": "^6.0.0",
|
|
||||||
"wrap-ansi": "^6.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/find-up": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"locate-path": "^5.0.0",
|
|
||||||
"path-exists": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/locate-path": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"p-locate": "^4.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/p-limit": {
|
|
||||||
"version": "2.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
|
||||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"p-try": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/p-locate": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"p-limit": "^2.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/wrap-ansi": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"ansi-styles": "^4.0.0",
|
|
||||||
"string-width": "^4.1.0",
|
|
||||||
"strip-ansi": "^6.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/y18n": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/yargs": {
|
|
||||||
"version": "15.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
|
||||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"cliui": "^6.0.0",
|
|
||||||
"decamelize": "^1.2.0",
|
|
||||||
"find-up": "^4.1.0",
|
|
||||||
"get-caller-file": "^2.0.1",
|
|
||||||
"require-directory": "^2.1.1",
|
|
||||||
"require-main-filename": "^2.0.0",
|
|
||||||
"set-blocking": "^2.0.0",
|
|
||||||
"string-width": "^4.2.0",
|
|
||||||
"which-module": "^2.0.0",
|
|
||||||
"y18n": "^4.0.0",
|
|
||||||
"yargs-parser": "^18.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qrcode/node_modules/yargs-parser": {
|
|
||||||
"version": "18.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
|
||||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"camelcase": "^5.0.0",
|
|
||||||
"decamelize": "^1.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/queue": {
|
"node_modules/queue": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
||||||
@@ -11327,17 +11111,12 @@
|
|||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/require-main-filename": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.10",
|
"version": "1.22.10",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||||
@@ -12143,6 +11922,7 @@
|
|||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"emoji-regex": "^8.0.0",
|
"emoji-regex": "^8.0.0",
|
||||||
@@ -12157,6 +11937,7 @@
|
|||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/string.prototype.includes": {
|
"node_modules/string.prototype.includes": {
|
||||||
@@ -12270,6 +12051,7 @@
|
|||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-regex": "^5.0.1"
|
"ansi-regex": "^5.0.1"
|
||||||
@@ -12731,16 +12513,6 @@
|
|||||||
"node": ">= 10.0.0"
|
"node": ">= 10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/unpipe": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/unrs-resolver": {
|
"node_modules/unrs-resolver": {
|
||||||
"version": "1.7.2",
|
"version": "1.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.7.2.tgz",
|
||||||
@@ -13088,13 +12860,6 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yallist": {
|
|
||||||
"version": "3.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
|
||||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
|
||||||
"license": "ISC",
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/yargs": {
|
"node_modules/yargs": {
|
||||||
"version": "17.7.2",
|
"version": "17.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { NextRequest, NextResponse } from 'next/server';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
|
||||||
import { Connection, ParsedTransactionWithMeta } from '@solana/web3.js';
|
import { Connection } from '@solana/web3.js';
|
||||||
|
|
||||||
import { verifyUnusedSolanaPayment } from '@/utils/solana-verify';
|
import { verifyUnusedSolanaPayment } from '@/utils/solana-verify';
|
||||||
import { transferLNTTokens } from '@/services/laconic-transfer';
|
import { transferLNTTokens } from '@/services/laconic-transfer';
|
||||||
@@ -25,7 +25,6 @@ const ALLOWED_SLIPPAGE_FACTOR = 0.2
|
|||||||
|
|
||||||
// Use CAIP convention for chain ID: namespace + reference
|
// Use CAIP convention for chain ID: namespace + reference
|
||||||
const SOLANA_CHAIN_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'; // Solana mainnet
|
const SOLANA_CHAIN_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'; // Solana mainnet
|
||||||
const GORBAGANA_CHAIN_ID = 'gorbagana:533uBE9RRquhTBqEX58oV52FdTTsReMd' // Gorbagana chain (first 32 characters of gorbagana genesis hash. Following solana CAIP chain ID pattern)
|
|
||||||
|
|
||||||
// Sleep helper function
|
// Sleep helper function
|
||||||
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
@@ -168,7 +167,6 @@ export async function POST(request: NextRequest) {
|
|||||||
// First check if the request body is valid JSON
|
// First check if the request body is valid JSON
|
||||||
let url, txHash, senderPublicKey, paymentMethod;
|
let url, txHash, senderPublicKey, paymentMethod;
|
||||||
let connection: Connection;
|
let connection: Connection;
|
||||||
let parsedTx: ParsedTransactionWithMeta | null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
@@ -188,8 +186,6 @@ export async function POST(request: NextRequest) {
|
|||||||
}, { status: 400 });
|
}, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedTx = tx;
|
|
||||||
|
|
||||||
const signerKeys = tx.transaction.message.accountKeys
|
const signerKeys = tx.transaction.message.accountKeys
|
||||||
.filter(k => k.signer)
|
.filter(k => k.signer)
|
||||||
.map(k => k.pubkey.toBase58());
|
.map(k => k.pubkey.toBase58());
|
||||||
@@ -247,13 +243,9 @@ export async function POST(request: NextRequest) {
|
|||||||
const requiredAmountInBaseUnits = requiredTokenInfo.requiredAmountInBaseUnits;
|
const requiredAmountInBaseUnits = requiredTokenInfo.requiredAmountInBaseUnits;
|
||||||
const expectedTokenAmount = Math.round(requiredAmountInBaseUnits - ALLOWED_SLIPPAGE_FACTOR * requiredAmountInBaseUnits);
|
const expectedTokenAmount = Math.round(requiredAmountInBaseUnits - ALLOWED_SLIPPAGE_FACTOR * requiredAmountInBaseUnits);
|
||||||
|
|
||||||
if (!parsedTx) {
|
|
||||||
throw new Error(`Unable to find the tx with hash: ${txHash}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const solanaPaymentResult = await verifyUnusedSolanaPayment(
|
const solanaPaymentResult = await verifyUnusedSolanaPayment(
|
||||||
connection,
|
connection,
|
||||||
parsedTx,
|
txHash,
|
||||||
new BN(expectedTokenAmount),
|
new BN(expectedTokenAmount),
|
||||||
paymentMethod,
|
paymentMethod,
|
||||||
);
|
);
|
||||||
@@ -465,7 +457,7 @@ export async function POST(request: NextRequest) {
|
|||||||
repository_ref: fullHash,
|
repository_ref: fullHash,
|
||||||
},
|
},
|
||||||
external_payment: {
|
external_payment: {
|
||||||
chain_id: paymentMethod === PaymentMethod.SPL_TOKEN ? SOLANA_CHAIN_ID : GORBAGANA_CHAIN_ID,
|
chain_id: SOLANA_CHAIN_ID,
|
||||||
tx_hash: txHash,
|
tx_hash: txHash,
|
||||||
pubkey: senderPublicKey
|
pubkey: senderPublicKey
|
||||||
},
|
},
|
||||||
@@ -524,4 +516,4 @@ export async function POST(request: NextRequest) {
|
|||||||
message: error instanceof Error ? error.message : 'Unknown error',
|
message: error instanceof Error ? error.message : 'Unknown error',
|
||||||
}, { status: 500 });
|
}, { status: 500 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+20
-53
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useCallback, useEffect, useState, useRef, useMemo } from 'react';
|
import { useCallback, useEffect, useState, useRef } from 'react';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
|
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
|
||||||
@@ -27,14 +27,6 @@ const PaymentModal = dynamic(() => import('@/components/PaymentModal'), { ssr: f
|
|||||||
// RPC endpoint reference: https://docs.gorbagana.wtf/testnet-v2-devnet.html
|
// RPC endpoint reference: https://docs.gorbagana.wtf/testnet-v2-devnet.html
|
||||||
const GORBAGANA_GENESIS_HASH = '533uBE9RRquhTBqEX58oV52FdTTsReMdAvaUvP6hNjsn';
|
const GORBAGANA_GENESIS_HASH = '533uBE9RRquhTBqEX58oV52FdTTsReMdAvaUvP6hNjsn';
|
||||||
|
|
||||||
// Use following curl request to get Solana chain genesis hash:
|
|
||||||
// curl https://api.mainnet-beta.solana.com \
|
|
||||||
// -X POST \
|
|
||||||
// -H "Content-Type: application/json" \
|
|
||||||
// --data '{"jsonrpc":"2.0","id":1,"method":"getGenesisHash"}'
|
|
||||||
// RPC endpoint reference: https://solana.com/docs/references/clusters#on-a-high-level
|
|
||||||
const SOLANA_GENESIS_HASH = '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d';
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const { wallet, connected, publicKey, disconnect } = useWallet();
|
const { wallet, connected, publicKey, disconnect } = useWallet();
|
||||||
|
|
||||||
@@ -50,8 +42,7 @@ export default function Home() {
|
|||||||
const [appName, setAppName] = useState<string | null>(null);
|
const [appName, setAppName] = useState<string | null>(null);
|
||||||
const [repoUrl, setRepoUrl] = useState<string | null>(null);
|
const [repoUrl, setRepoUrl] = useState<string | null>(null);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [incorrectChainWarning, setIncorrectChainWarning] = useState<string | null>(null);
|
const [incorrectChainWarining, setIncorrectChainWarining] = useState<string | null>(null);
|
||||||
const [isFetchingChainGenesisHash, setIsFetchingChainGenesisHash] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!IS_NAT_GOR_TRANSFER_ENABLED) {
|
if (!IS_NAT_GOR_TRANSFER_ENABLED) {
|
||||||
@@ -60,38 +51,20 @@ export default function Home() {
|
|||||||
}, [setSelectedPaymentMethod]);
|
}, [setSelectedPaymentMethod]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIncorrectChainWarning(null);
|
if (!wallet || wallet.adapter.name !== BackpackWalletName || selectedPaymentMethod !== PaymentMethod.NAT_GOR) {
|
||||||
if (!wallet || wallet.adapter.name !== BackpackWalletName || !connected || !selectedPaymentMethod) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const warnOnIncorrectChain = async () => {
|
const warnOnIncorrectChain = async () => {
|
||||||
setIsFetchingChainGenesisHash(true);
|
// @ts-expect-error: backpack exists on window object
|
||||||
|
const genesisHash = await window.backpack.solana.connection.getGenesisHash();
|
||||||
try {
|
if (genesisHash !== GORBAGANA_GENESIS_HASH) {
|
||||||
// @ts-expect-error: backpack exists on window object
|
setIncorrectChainWarining("WARNING: Unsupported chain selected in wallet. Please switch to Gorbagana chain")
|
||||||
const genesisHash = await window.backpack.solana.connection.getGenesisHash();
|
|
||||||
|
|
||||||
const expectedGenesisHash = selectedPaymentMethod === PaymentMethod.NAT_GOR
|
|
||||||
? GORBAGANA_GENESIS_HASH
|
|
||||||
: SOLANA_GENESIS_HASH;
|
|
||||||
|
|
||||||
const expectedChainName = selectedPaymentMethod === PaymentMethod.NAT_GOR
|
|
||||||
? "Gorbagana"
|
|
||||||
: "Solana";
|
|
||||||
|
|
||||||
if (genesisHash !== expectedGenesisHash) {
|
|
||||||
setIncorrectChainWarning(
|
|
||||||
`Unsupported network selected in wallet. Please switch to network for ${expectedChainName} chain and reconnect the wallet.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
setIsFetchingChainGenesisHash(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
warnOnIncorrectChain();
|
warnOnIncorrectChain();
|
||||||
}, [wallet, selectedPaymentMethod, connected]);
|
}, [wallet, selectedPaymentMethod]);
|
||||||
|
|
||||||
// Track previous payment method to detect switches
|
// Track previous payment method to detect switches
|
||||||
const previousPaymentMethodRef = useRef<PaymentMethod | null>(null);
|
const previousPaymentMethodRef = useRef<PaymentMethod | null>(null);
|
||||||
@@ -117,7 +90,7 @@ export default function Home() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Helper function to check if current wallet is compatible with selected payment method
|
// Helper function to check if current wallet is compatible with selected payment method
|
||||||
const isWalletCompatible = useMemo(() => {
|
const isWalletCompatible = () => {
|
||||||
if (!selectedPaymentMethod || !wallet) return false;
|
if (!selectedPaymentMethod || !wallet) return false;
|
||||||
|
|
||||||
const walletName = wallet.adapter.name.toLowerCase();
|
const walletName = wallet.adapter.name.toLowerCase();
|
||||||
@@ -126,9 +99,9 @@ export default function Home() {
|
|||||||
if (selectedPaymentMethod === PaymentMethod.NAT_GOR) {
|
if (selectedPaymentMethod === PaymentMethod.NAT_GOR) {
|
||||||
return isBackpack; // Only Backpack for native GOR
|
return isBackpack; // Only Backpack for native GOR
|
||||||
} else {
|
} else {
|
||||||
return true; // Only non-Backpack wallets for SPL tokens
|
return !isBackpack; // Only non-Backpack wallets for SPL tokens
|
||||||
}
|
}
|
||||||
}, [selectedPaymentMethod, wallet]);
|
};
|
||||||
|
|
||||||
const handlePaymentComplete = useCallback(async (hash: string, paymentMethod: PaymentMethod) => {
|
const handlePaymentComplete = useCallback(async (hash: string, paymentMethod: PaymentMethod) => {
|
||||||
if (!publicKey || !url) {
|
if (!publicKey || !url) {
|
||||||
@@ -220,7 +193,7 @@ export default function Home() {
|
|||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<h3 className="font-semibold text-lg mb-2">{process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL} Token</h3>
|
<h3 className="font-semibold text-lg mb-2">{process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL} Token</h3>
|
||||||
<p className="text-xs mt-1" style={{ color: 'var(--muted-foreground)' }}>
|
<p className="text-xs mt-1" style={{ color: 'var(--muted-foreground)' }}>
|
||||||
Compatible with: All Solana compatible wallets
|
Compatible with: Phantom, Solflare
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
@@ -252,28 +225,23 @@ export default function Home() {
|
|||||||
<div className="flex flex-col items-center space-y-3">
|
<div className="flex flex-col items-center space-y-3">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<span className="w-3 h-3 rounded-full mr-2" style={{
|
<span className="w-3 h-3 rounded-full mr-2" style={{
|
||||||
backgroundColor: isWalletCompatible ? 'var(--success)' : 'var(--destructive)'
|
backgroundColor: isWalletCompatible() ? 'var(--success)' : 'var(--destructive)'
|
||||||
}}></span>
|
}}></span>
|
||||||
<p className="font-medium" style={{
|
<p className="font-medium" style={{
|
||||||
color: isWalletCompatible ? 'var(--success)' : 'var(--destructive)'
|
color: isWalletCompatible() ? 'var(--success)' : 'var(--destructive)'
|
||||||
}}>
|
}}>
|
||||||
{isWalletCompatible ? 'Compatible' : 'Incompatible'} Wallet ({wallet?.adapter.name})
|
{isWalletCompatible() ? 'Compatible' : 'Incompatible'} Wallet ({wallet?.adapter.name})
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{!isWalletCompatible && (
|
{!isWalletCompatible() && (
|
||||||
<p className="text-sm text-amber-400">
|
<p className="text-sm text-amber-400">
|
||||||
This wallet is not compatible with {PAYMENT_METHOD_LABELS[selectedPaymentMethod]} payments.
|
This wallet is not compatible with {PAYMENT_METHOD_LABELS[selectedPaymentMethod]} payments.
|
||||||
Please select a different wallet or payment method.
|
Please select a different wallet or payment method.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{ isFetchingChainGenesisHash && (
|
{incorrectChainWarining && (
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
Checking wallet network compatibility...
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
{incorrectChainWarning && (
|
|
||||||
<p className="text-sm text-amber-400">
|
<p className="text-sm text-amber-400">
|
||||||
{incorrectChainWarning}
|
{incorrectChainWarining}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<div className="w-full p-3 rounded-md" style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)' }}>
|
<div className="w-full p-3 rounded-md" style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)' }}>
|
||||||
@@ -308,19 +276,18 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Step 3: URL Input */}
|
{/* Step 3: URL Input */}
|
||||||
<div className="mb-8 p-6 rounded-lg" style={{
|
<div className="mb-8 p-6 rounded-lg" style={{
|
||||||
background: 'var(--muted-light)',
|
background: 'var(--muted-light)',
|
||||||
borderLeft: '4px solid var(--primary)',
|
borderLeft: '4px solid var(--primary)',
|
||||||
opacity: (connected && isWalletCompatible) ? '1' : '0.6'
|
opacity: (connected && isWalletCompatible()) ? '1' : '0.6'
|
||||||
}}>
|
}}>
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center">
|
<h2 className="text-lg font-semibold mb-4 flex items-center">
|
||||||
Enter URL to Deploy
|
Enter URL to Deploy
|
||||||
</h2>
|
</h2>
|
||||||
<URLForm
|
<URLForm
|
||||||
onSubmit={handleUrlSubmit}
|
onSubmit={handleUrlSubmit}
|
||||||
disabled={!connected || !isWalletCompatible || isFetchingChainGenesisHash || status === 'creating' || Boolean(incorrectChainWarning)}
|
disabled={!connected || !isWalletCompatible() || status === 'creating'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export default function URLForm({ onSubmit, disabled }: URLFormProps) {
|
|||||||
opacity: (disabled || !url) ? '0.7' : '1',
|
opacity: (disabled || !url) ? '0.7' : '1',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Deploy URL
|
{disabled ? 'Connect Wallet First' : 'Deploy URL'}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ import { PaymentMethod } from '@/types';
|
|||||||
import '@solana/wallet-adapter-react-ui/styles.css';
|
import '@solana/wallet-adapter-react-ui/styles.css';
|
||||||
|
|
||||||
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
|
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
|
||||||
assert(process.env.NEXT_PUBLIC_SOLANA_WS_URL, 'SOLANA_WS_URL is required');
|
|
||||||
|
|
||||||
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
|
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
|
||||||
const SOLANA_WS_URL = process.env.NEXT_PUBLIC_SOLANA_WS_URL;
|
|
||||||
|
|
||||||
interface WalletProvidersProps {
|
interface WalletProvidersProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -62,7 +59,7 @@ export default function WalletProviders({ children }: WalletProvidersProps) {
|
|||||||
}, [allWallets, selectedPaymentMethod]);
|
}, [allWallets, selectedPaymentMethod]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConnectionProvider endpoint={endpoint} config={{wsEndpoint: SOLANA_WS_URL}}>
|
<ConnectionProvider endpoint={endpoint}>
|
||||||
<WalletProvider wallets={wallets} autoConnect>
|
<WalletProvider wallets={wallets} autoConnect>
|
||||||
<WalletModalProvider>
|
<WalletModalProvider>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
+14
-11
@@ -1,6 +1,6 @@
|
|||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
|
|
||||||
import { Connection, ParsedInstruction, ParsedTransactionWithMeta, PartiallyDecodedInstruction } from '@solana/web3.js';
|
import { Connection, ParsedInstruction, PartiallyDecodedInstruction } from '@solana/web3.js';
|
||||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||||
|
|
||||||
import { getRecipientAddress } from '@/services/solana';
|
import { getRecipientAddress } from '@/services/solana';
|
||||||
@@ -9,11 +9,12 @@ import { PaymentMethod } from '../types';
|
|||||||
// Extract transaction info for native GOR transfers
|
// Extract transaction info for native GOR transfers
|
||||||
const extractTxInfo = async (
|
const extractTxInfo = async (
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
parsedTx: ParsedTransactionWithMeta,
|
transactionSignature: string,
|
||||||
paymentMethod: PaymentMethod
|
paymentMethod: PaymentMethod
|
||||||
): Promise<{ authority: string; amount: string; destination: string }> => {
|
): Promise<{ authority: string; amount: string; destination: string }> => {
|
||||||
|
const result = await connection.getParsedTransaction(transactionSignature, 'confirmed');
|
||||||
|
|
||||||
if (!parsedTx) {
|
if (!result) {
|
||||||
throw new Error('Transaction not found');
|
throw new Error('Transaction not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ const extractTxInfo = async (
|
|||||||
switch (paymentMethod) {
|
switch (paymentMethod) {
|
||||||
case PaymentMethod.NAT_GOR:
|
case PaymentMethod.NAT_GOR:
|
||||||
// Look for system program transfer instruction
|
// Look for system program transfer instruction
|
||||||
transferInstruction = parsedTx.transaction.message.instructions.find(
|
transferInstruction = result.transaction.message.instructions.find(
|
||||||
(instr) => 'parsed' in instr && instr.parsed.type === 'transfer'
|
(instr) => 'parsed' in instr && instr.parsed.type === 'transfer'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ const extractTxInfo = async (
|
|||||||
|
|
||||||
case PaymentMethod.SPL_TOKEN:
|
case PaymentMethod.SPL_TOKEN:
|
||||||
// Look for token transfer instruction using TOKEN_PROGRAM_ID
|
// Look for token transfer instruction using TOKEN_PROGRAM_ID
|
||||||
transferInstruction = parsedTx.transaction.message.instructions.find(
|
transferInstruction = result.transaction.message.instructions.find(
|
||||||
(instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID)
|
(instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ const extractTxInfo = async (
|
|||||||
|
|
||||||
export const verifyUnusedSolanaPayment = async (
|
export const verifyUnusedSolanaPayment = async (
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
parsedTx: ParsedTransactionWithMeta,
|
transactionSignature: string,
|
||||||
expectedAmount: BN,
|
expectedAmount: BN,
|
||||||
paymentMethod: PaymentMethod,
|
paymentMethod: PaymentMethod,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
@@ -80,7 +81,9 @@ export const verifyUnusedSolanaPayment = async (
|
|||||||
// TODO: Check if provided signature is already used
|
// TODO: Check if provided signature is already used
|
||||||
|
|
||||||
// Fetch transaction details
|
// Fetch transaction details
|
||||||
if (!parsedTx) {
|
const transactionResult = await connection.getParsedTransaction(transactionSignature, 'confirmed');
|
||||||
|
|
||||||
|
if (!transactionResult) {
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
reason: 'Transaction not found on Solana blockchain'
|
reason: 'Transaction not found on Solana blockchain'
|
||||||
@@ -88,15 +91,15 @@ export const verifyUnusedSolanaPayment = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if transaction was successful
|
// Check if transaction was successful
|
||||||
if (parsedTx.meta?.err) {
|
if (transactionResult.meta?.err) {
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
reason: `Transaction failed: ${JSON.stringify(parsedTx.meta.err)}`
|
reason: `Transaction failed: ${JSON.stringify(transactionResult.meta.err)}`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check transaction timestamp (5-minute window)
|
// Check transaction timestamp (5-minute window)
|
||||||
const txTimestamp = parsedTx.blockTime ? new Date(parsedTx.blockTime * 1000) : null;
|
const txTimestamp = transactionResult.blockTime ? new Date(transactionResult.blockTime * 1000) : null;
|
||||||
if (!txTimestamp) {
|
if (!txTimestamp) {
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
@@ -116,7 +119,7 @@ export const verifyUnusedSolanaPayment = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract transaction info based on payment method
|
// Extract transaction info based on payment method
|
||||||
const transferInfo = await extractTxInfo(connection, parsedTx, paymentMethod);
|
const transferInfo = await extractTxInfo(connection, transactionSignature, paymentMethod);
|
||||||
const amount = transferInfo.amount;
|
const amount = transferInfo.amount;
|
||||||
const authority = transferInfo.authority;
|
const authority = transferInfo.authority;
|
||||||
const destination = transferInfo.destination;
|
const destination = transferInfo.destination;
|
||||||
|
|||||||
Reference in New Issue
Block a user