Add steps to publish PricingRecord
and use it for determining cost of deployments (#4)
Part of https://www.notion.so/Laconic-Mainnet-Plan-1eca6b22d47280569cd0d1e6d711d949 Co-authored-by: Shreerang Kale <shreerangkale@gmail.com> Reviewed-on: #4 Co-authored-by: shreerang <shreerang@noreply.git.vdb.to> Co-committed-by: shreerang <shreerang@noreply.git.vdb.to>
This commit is contained in:
parent
fbe4eed31d
commit
452c4db5f8
15
.env.example
15
.env.example
@ -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
|
||||
# TODO: Use different RPC URL or use browser wallet
|
||||
# TODO: Use different RPC URL
|
||||
NEXT_PUBLIC_SOLANA_RPC_URL=https://skilled-prettiest-seed.solana-mainnet.quiknode.pro/eeecfebd04e345f69f1900cc3483cbbfea02a158
|
||||
NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS=71Jvq4Epe2FCJ7JFSF7jLXdNk1Wy4Bhqd9iL6bEFELvg
|
||||
NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL=GOR
|
||||
NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD=5
|
||||
|
||||
# Gorbagana Chain Configuration
|
||||
NEXT_PUBLIC_GORBAGANA_RPC_URL=https://rpc.gorbagana.wtf
|
||||
@ -17,12 +16,12 @@ NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS=FFDx3SdAEeXrp6BTmStB4BDHpctGsaasZq4FF
|
||||
# UI Configuration
|
||||
NEXT_PUBLIC_EXAMPLE_URL=https://git.vdb.to/cerc-io/test-progressive-web-app
|
||||
|
||||
# Server-side environment variables
|
||||
|
||||
# Laconic Registry Configuration
|
||||
REGISTRY_CHAIN_ID=laconic-mainnet
|
||||
REGISTRY_RPC_ENDPOINT=https://laconicd-mainnet-1.laconic.com
|
||||
REGISTRY_GQL_ENDPOINT=https://laconicd-mainnet-1.laconic.com/graphql
|
||||
NEXT_PUBLIC_REGISTRY_CHAIN_ID=laconic-mainnet
|
||||
NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT=https://laconicd-mainnet-1.laconic.com
|
||||
NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT=https://laconicd-mainnet-1.laconic.com/graphql
|
||||
NEXT_PUBLIC_ALNT_COST_LRN=lrn://laconic/pricing/alnt
|
||||
NEXT_PUBLIC_DEPLOYMENT_COST_LRN=lrn://laconic/pricing/webapp-deployment
|
||||
REGISTRY_GAS_PRICE=0.001
|
||||
REGISTRY_BOND_ID=
|
||||
REGISTRY_AUTHORITY=
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -43,3 +43,6 @@ yarn-error.log*
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
|
||||
# Reveal file out dir
|
||||
out
|
@ -106,9 +106,9 @@ NEXT_PUBLIC_EXAMPLE_URL=https://git.vdb.to/cerc-io/test-progressive-web-app
|
||||
|
||||
### Server-side Variables
|
||||
```bash
|
||||
REGISTRY_CHAIN_ID=laconic-mainnet
|
||||
REGISTRY_GQL_ENDPOINT=https://laconicd-mainnet-1.laconic.com/api
|
||||
REGISTRY_RPC_ENDPOINT=https://laconicd-mainnet-1.laconic.com
|
||||
NEXT_PUBLIC_REGISTRY_CHAIN_ID=laconic-mainnet
|
||||
NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT=https://laconicd-mainnet-1.laconic.com/api
|
||||
NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT=https://laconicd-mainnet-1.laconic.com
|
||||
REGISTRY_BOND_ID=<BOND_ID>
|
||||
REGISTRY_AUTHORITY=<AUTHORITY_NAME>
|
||||
REGISTRY_USER_KEY=<PRIVATE_KEY>
|
||||
|
102
README.md
102
README.md
@ -20,35 +20,9 @@ A simple Next.js frontend that allows users to pay in GOR tokens (configurable S
|
||||
- Solana wallet browser extension (Phantom or Solflare)
|
||||
- Access to a Laconic Registry node
|
||||
|
||||
## Environment Variables
|
||||
## Deploy to production
|
||||
|
||||
Copy the `.env.local.example` file to `.env.local` and fill in the required variables:
|
||||
|
||||
```bash
|
||||
cp .env.local.example .env.local
|
||||
```
|
||||
|
||||
Required environment variables:
|
||||
|
||||
Client-side (must be prefixed with NEXT_PUBLIC_):
|
||||
- `NEXT_PUBLIC_SOLANA_RPC_URL` - The RPC URL for the Solana blockchain
|
||||
- `NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS` - The mint address of the SPL token to accept
|
||||
- `NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS` - The Solana address that will receive token payments
|
||||
- `NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL` - The token symbol to display (e.g., "GOR")
|
||||
- `NEXT_PUBLIC_SOLANA_TOKEN_DECIMALS` - The number of decimals for the token (e.g., 6)
|
||||
- `NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT` - The fixed payment amount required (e.g., 400)
|
||||
- `NEXT_PUBLIC_DOMAIN_SUFFIX` - Optional suffix to append to DNS names in the UI (e.g. ".example.com")
|
||||
- `NEXT_PUBLIC_EXAMPLE_URL` - Example URL to pre-fill in the URL form (e.g. "https://github.com/cerc-io/laconic-registry-cli")
|
||||
|
||||
Server-side:
|
||||
- `REGISTRY_CHAIN_ID` - The chain ID for the Laconic Registry
|
||||
- `REGISTRY_GQL_ENDPOINT` - The GraphQL endpoint for the Laconic Registry
|
||||
- `REGISTRY_RPC_ENDPOINT` - The RPC endpoint for the Laconic Registry
|
||||
- `REGISTRY_BOND_ID` - The bond ID to use for Laconic Registry records
|
||||
- `REGISTRY_AUTHORITY` - The authority for Laconic Registry LRNs
|
||||
- `REGISTRY_USER_KEY` - The private key for Laconic Registry transactions (also used for LNT transfers)
|
||||
- `APP_NAME` - The name of the application (used in record creation, defaults to "gor-deploy")
|
||||
- `DEPLOYER_LRN` - The LRN of the deployer
|
||||
Follow [these steps](./deploy/README.md) to deploy this app to production
|
||||
|
||||
## Installation
|
||||
|
||||
@ -58,6 +32,35 @@ npm install
|
||||
|
||||
## Development
|
||||
|
||||
Copy the `.env.example` file to `.env.local` and fill in the required variables:
|
||||
|
||||
```bash
|
||||
cp .env.example .env.local
|
||||
```
|
||||
|
||||
Required environment variables:
|
||||
|
||||
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_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_GORBAGANA_RPC_URL` - The RPC URL for the Gorbagana blockchain (native GOR transactions)
|
||||
- `NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER` - Enable native GOR token transfers (true/false)
|
||||
- `NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS` - The Solana address that will receive token payments
|
||||
- `NEXT_PUBLIC_EXAMPLE_URL` - Example URL to pre-fill in the URL form
|
||||
- `NEXT_PUBLIC_REGISTRY_CHAIN_ID` - The laconicd chain ID for the Laconic Registry
|
||||
- `NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT` - The laconicd RPC endpoint for the Laconic Registry
|
||||
- `NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT` - The laconicd GraphQL endpoint for the Laconic Registry
|
||||
- `NEXT_PUBLIC_ALNT_COST_LRN` - LRN for ALNT token pricing
|
||||
- `NEXT_PUBLIC_DEPLOYMENT_COST_LRN` - LRN for deployment cost pricing
|
||||
- `NEXT_PUBLIC_DOMAIN_SUFFIX` - Optional suffix to append to DNS names in the UI (e.g. ".example.com")
|
||||
|
||||
Server-side:
|
||||
- `REGISTRY_BOND_ID` - The bond ID to use for Laconic Registry records
|
||||
- `REGISTRY_AUTHORITY` - The authority for Laconic Registry LRNs
|
||||
- `REGISTRY_USER_KEY` - The private key for Laconic Registry transactions (also used for LNT transfers)
|
||||
- `DEPLOYER_LRN` - The LRN of the deployer
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
@ -130,43 +133,6 @@ This application was built with reference to:
|
||||
- `snowballtools-base/packages/backend/src/registry.ts`
|
||||
- Original `hosted-frontends/deploy-atom.sh` (adapted for Solana/GOR)
|
||||
|
||||
## Deployment to Production
|
||||
|
||||
To deploy this application to production, follow these steps:
|
||||
|
||||
1. Clone the repository
|
||||
2. Install dependencies: `npm install`
|
||||
3. Create a production build: `npm run build`
|
||||
4. Set up all required environment variables in your production environment
|
||||
5. Start the production server: `npm start`
|
||||
|
||||
For containerized deployments, you can use the following Dockerfile:
|
||||
|
||||
```dockerfile
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
Build and run the Docker container:
|
||||
|
||||
```bash
|
||||
docker build -t gor-deploy .
|
||||
docker run -p 3000:3000 --env-file .env.production gor-deploy
|
||||
```
|
||||
|
||||
## Known Issues
|
||||
|
||||
- You may see a deprecated Buffer() warning during build. This comes from dependencies in the registry-sdk. This doesn't affect functionality.
|
||||
@ -181,12 +147,6 @@ docker run -p 3000:3000 --env-file .env.production gor-deploy
|
||||
- **Connection issues**: Ensure the wallet is unlocked and try refreshing the page.
|
||||
- **Transaction failures**: Check that you have sufficient SOL for transaction fees and enough tokens for the payment.
|
||||
|
||||
### Token Configuration
|
||||
|
||||
- **Wrong token**: Verify the `NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS` matches your desired SPL token.
|
||||
- **Incorrect decimals**: Ensure `NEXT_PUBLIC_SOLANA_TOKEN_DECIMALS` matches the token's actual decimal count.
|
||||
- **Payment amount**: Adjust `NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT` to the desired payment amount.
|
||||
|
||||
### Laconic Registry Issues
|
||||
|
||||
- **Failed to create record**: Check that your REGISTRY_USER_KEY and REGISTRY_BOND_ID are correctly set.
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
### gor-deploy
|
||||
|
||||
* Clone the repo:
|
||||
- Clone the repo:
|
||||
|
||||
```bash
|
||||
git clone git@git.vdb.to:LaconicNetwork/gor-deploy.git
|
||||
cd gor-deploy/deploy
|
||||
```
|
||||
|
||||
* Build registry CLI image:
|
||||
- Build registry CLI image:
|
||||
|
||||
```bash
|
||||
docker build -t cerc/laconic-registry-cli .
|
||||
@ -19,13 +19,31 @@
|
||||
# Builds image cerc/laconic-registry-cli:latest
|
||||
```
|
||||
|
||||
* Configure `userKey` and `bondId` in the [registry CLI config](./config.yml):
|
||||
- Configure `userKey` and `bondId` in the [registry CLI config](./config.yml):
|
||||
|
||||
- User key should be of the account that owns the `laconic-deploy` authority (owner account address: `laconic1kwx2jm6vscz38qlyujvq6msujmk8l3zangqahs`)
|
||||
- The bond should also be owned by same user (owned bond's ID: `230cfedda15e78edc8986dfcb870e1b618f65c56e38d2735476d2a8cb3f25e38`)
|
||||
- If the authority is not available, follow [these steps to reserve a new authority](./publish-pricing.md#reserve-a-new-authority-optional)
|
||||
|
||||
```bash
|
||||
nano config.yml
|
||||
```
|
||||
|
||||
* Add configuration for registry operations:
|
||||
- This project requires pricing records for cost of deployment and cost of alnt to be published
|
||||
|
||||
- Check if these records are available by running following commands:
|
||||
|
||||
```bash
|
||||
# Check if `lrn://laconic/pricing/webapp-deployment` is available
|
||||
./laconic-cli.sh name resolve lrn://laconic/pricing/webapp-deployment
|
||||
|
||||
# Check if `lrn://laconic/pricing/alnt` is available
|
||||
./laconic-cli.sh name resolve lrn://laconic/pricing/alnt
|
||||
```
|
||||
|
||||
- If these records are not available, [follow these steps to publish them](./publish-pricing.md)
|
||||
|
||||
- Add configuration for registry operations:
|
||||
|
||||
```bash
|
||||
cp .registry.env.example .registry.env
|
||||
@ -34,7 +52,7 @@
|
||||
nano .registry.env
|
||||
```
|
||||
|
||||
* Add configuration for the app:
|
||||
- Add configuration for the app:
|
||||
|
||||
```bash
|
||||
curl -s https://git.vdb.to/LaconicNetwork/gor-deploy/src/branch/main/.env.example -o .app.env
|
||||
@ -43,11 +61,27 @@
|
||||
nano .app.env
|
||||
```
|
||||
|
||||
- Required environment variables:
|
||||
|
||||
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_GORBAGANA_RPC_URL` - The RPC URL for the Gorbagana blockchain (native GOR transactions)
|
||||
- `NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER` - Enable native GOR token transfers (true/false)
|
||||
- `NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS` - The Solana address that will receive token payments
|
||||
- `NEXT_PUBLIC_ALNT_COST_LRN` - LRN for ALNT token pricing
|
||||
- `NEXT_PUBLIC_DEPLOYMENT_COST_LRN` - LRN for deployment cost pricing
|
||||
- `NEXT_PUBLIC_DOMAIN_SUFFIX` - Suffix to append to DNS names in the UI (e.g. ".example.com")
|
||||
|
||||
Server-side:
|
||||
- `REGISTRY_BOND_ID` - The bond ID to use for Laconic Registry records
|
||||
- `REGISTRY_AUTHORITY` - The authority for Laconic Registry LRNs
|
||||
- `REGISTRY_USER_KEY` - The private key for Laconic Registry transactions (also used for LNT transfers)
|
||||
- `DEPLOYER_LRN` - The LRN of the deployer
|
||||
|
||||
## Run
|
||||
|
||||
### gor-deploy
|
||||
- Deploy `gor-deploy` App:
|
||||
|
||||
* Deploy `gor-deploy` App:
|
||||
```bash
|
||||
# In gor-deploy/deploy dir
|
||||
docker run -it \
|
||||
@ -57,13 +91,13 @@
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
* Check deployment logs on deployer UI: <https://webapp-deployer-ui.apps.vaasl.io/>
|
||||
- Check deployment logs on deployer UI: <https://webapp-deployer-ui.apps.vaasl.io/>
|
||||
|
||||
* Visit deployed app: <https://gor-deploy.apps.vaasl.io>
|
||||
- Visit deployed app: <https://gor-deploy.apps.vaasl.io>
|
||||
|
||||
### remove deployment
|
||||
### Remove deployment
|
||||
|
||||
* Remove deployment:
|
||||
- Remove deployment:
|
||||
|
||||
```bash
|
||||
# In gor-deploy/deploy dir
|
||||
|
50
deploy/laconic-cli.sh
Executable file
50
deploy/laconic-cli.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Laconic Registry CLI Docker wrapper script
|
||||
# This script wraps the Docker command to run laconic registry CLI commands
|
||||
# Run this script from the deploy directory
|
||||
|
||||
# Check if docker is available
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "Error: Docker is not installed or not in PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the cerc/laconic-registry-cli image exists
|
||||
if ! docker image inspect cerc/laconic-registry-cli &> /dev/null; then
|
||||
echo "Error: cerc/laconic-registry-cli Docker image not found"
|
||||
echo "Please build the image first: docker build -t cerc/laconic-registry-cli ."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get current directory (should be deploy directory)
|
||||
CURRENT_DIR="$(pwd)"
|
||||
PROJECT_ROOT="$(dirname "$CURRENT_DIR")"
|
||||
|
||||
# Verify we're in the deploy directory
|
||||
if [ ! -f "config.yml" ] || [ ! -f "laconic-cli.sh" ]; then
|
||||
echo "Error: This script must be run from the deploy directory"
|
||||
echo "Current directory: $CURRENT_DIR"
|
||||
echo "Please cd to the deploy directory and run: ./laconic-cli.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set up volume mounts
|
||||
DEPLOY_MOUNT="-v $CURRENT_DIR:/app/deploy"
|
||||
OUT_MOUNT=""
|
||||
|
||||
# Create out directory if it doesn't exist and always mount it
|
||||
if [ ! -d "out" ]; then
|
||||
mkdir -p "out"
|
||||
fi
|
||||
OUT_MOUNT="-v $CURRENT_DIR/out:/app/out"
|
||||
|
||||
# Run the Docker command with processed arguments
|
||||
docker run --rm \
|
||||
--add-host=host.docker.internal:host-gateway \
|
||||
$DEPLOY_MOUNT \
|
||||
$OUT_MOUNT \
|
||||
-w /app/deploy \
|
||||
cerc/laconic-registry-cli \
|
||||
laconic registry -c config.yml \
|
||||
"$@"
|
147
deploy/publish-pricing.md
Normal file
147
deploy/publish-pricing.md
Normal file
@ -0,0 +1,147 @@
|
||||
# publish-pricing
|
||||
|
||||
## Setup
|
||||
|
||||
- Clone the repo:
|
||||
|
||||
```bash
|
||||
git clone git@git.vdb.to:LaconicNetwork/gor-deploy.git
|
||||
cd gor-deploy/deploy
|
||||
```
|
||||
|
||||
- Build the Docker container:
|
||||
|
||||
```bash
|
||||
docker build -t cerc/laconic-registry-cli .
|
||||
|
||||
# Builds image cerc/laconic-registry-cli:latest
|
||||
```
|
||||
|
||||
- Configure `userKey` in the [registry CLI config](./config.yml):
|
||||
|
||||
NOTE: The `laconic` authority is required to set the published record names so the user key should be of the account that owns the `laconic` authority (owner account address: `laconic13maulvmjxnyx3g855vk0lsv5aptf3rpxskynef`). If you don't have an authority check [steps to reserve a new authority](#reserve-a-new-authority-optional)
|
||||
|
||||
```bash
|
||||
nano config.yml
|
||||
```
|
||||
|
||||
## Publish Record and Set Record Name
|
||||
|
||||
Publishing record requires a bond with enough funds as rent is taken for each record from the bond every year
|
||||
|
||||
The rent amount taken is `1000000alnt` so maintaining a bond with about 10x the rent amount i.e `10000000alnt` is recommended
|
||||
|
||||
Make sure, the record names are under `laconic` authority
|
||||
|
||||
### Publish Record for Cost of alnt
|
||||
|
||||
- alnt price calculation (reference: <https://store.laconic.com>):
|
||||
- Cost of 1 deployment is `12960` in terms of `alnt` or `5` in terms of `USD`
|
||||
- Hence, cost of 1 `alnt` comes out be `0.000386 USD` rounded off to 6 decimals
|
||||
|
||||
- Publish the record:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh record publish --filename records/alnt-pricing.yml --bond-id <bond-id>
|
||||
```
|
||||
|
||||
- Get record info:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh record get --id <record-id>
|
||||
```
|
||||
|
||||
- Set record name for cost of alnt record:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh name set lrn://laconic/pricing/alnt <record-id>
|
||||
```
|
||||
|
||||
### Publish Record for Cost of Deployment
|
||||
|
||||
- Publish the record:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh record publish --filename records/webapp-deployment-pricing.yml --bond-id <bond-id>
|
||||
```
|
||||
|
||||
- Get record info:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh record get --id <record-id>
|
||||
```
|
||||
|
||||
- Set record name for cost of deployment record
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh name set lrn://laconic/pricing/webapp-deployment <record-id>
|
||||
```
|
||||
|
||||
- Now you should be able to use these records in the app
|
||||
|
||||
- You can now continue with [steps to deploy the app](./README.md)
|
||||
|
||||
## Create Bond (optional)
|
||||
|
||||
- Create bond:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh bond create --type alnt --quantity 10000000
|
||||
```
|
||||
|
||||
- Get bond info:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh bond get --id <bond-id>
|
||||
```
|
||||
|
||||
## Reserve a New Authority (optional)
|
||||
|
||||
Below steps are used to reserve `laconic` authority
|
||||
|
||||
- Reserve authority:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh authority reserve laconic
|
||||
```
|
||||
|
||||
- After reserving authority, commit phase begins which lasts for 1 minute so please commit the bid following below steps within that time period
|
||||
|
||||
- Check authority info:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh authority whois laconic
|
||||
```
|
||||
|
||||
- Note down auction ID from authority info as it is required in next steps
|
||||
|
||||
- Get auction info:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh auction get <auction-id>
|
||||
```
|
||||
|
||||
- Commit an auction bid:
|
||||
|
||||
```bash
|
||||
# 5000000 alnt is the minimum bid amount for authority auction
|
||||
|
||||
./laconic-cli.sh auction bid commit <auction-id> 5000000 alnt
|
||||
|
||||
# Example file path inside container
|
||||
Reveal file: /app/deploy/out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json
|
||||
```
|
||||
|
||||
- The reveal phase starts as soon as commit phase ends and lasts for 1 minute so please reveal the bid within this time period
|
||||
|
||||
- Reveal bid:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh auction bid reveal <auction-id> /app/deploy/out/<reaveal-file>.json
|
||||
```
|
||||
|
||||
- Set authority bond after winning auction as it is required to use the published authority:
|
||||
|
||||
```bash
|
||||
./laconic-cli.sh authority bond set laconic <bond-id>
|
||||
```
|
6
deploy/records/alnt-pricing.yml
Normal file
6
deploy/records/alnt-pricing.yml
Normal file
@ -0,0 +1,6 @@
|
||||
record:
|
||||
type: PricingRecord
|
||||
for: "alnt"
|
||||
amount: "0.000386"
|
||||
currency: "USD"
|
||||
version: 1.0.0
|
6
deploy/records/webapp-deployment-pricing.yml
Normal file
6
deploy/records/webapp-deployment-pricing.yml
Normal file
@ -0,0 +1,6 @@
|
||||
record:
|
||||
type: PricingRecord
|
||||
for: "webapp-deployment"
|
||||
amount: "12960"
|
||||
currency: "alnt"
|
||||
version: 1.0.0
|
310
package-lock.json
generated
310
package-lock.json
generated
@ -25,6 +25,7 @@
|
||||
"react-dom": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cerc-io/laconic-registry-cli": "^0.2.9",
|
||||
"@eslint/eslintrc": "^3",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
@ -515,72 +516,47 @@
|
||||
"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,
|
||||
"node_modules/@cerc-io/laconic-registry-cli": {
|
||||
"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",
|
||||
"integrity": "sha512-rwrZhFgYZiMh2k+9E/aiyRhFLApydRUwclATb0f6hsFAkxARuaibHsJNy7eF2N/AQ4d6HAvpkXACJoVrGOppmw==",
|
||||
"dev": true,
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/parser": "^7.27.2",
|
||||
"@babel/types": "^7.27.1"
|
||||
"@cerc-io/registry-sdk": "^0.2.11",
|
||||
"@cosmjs/stargate": "^0.32.2",
|
||||
"fs-extra": "^10.1.0",
|
||||
"js-yaml": "^3.14.1",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-clean": "^2.2.3",
|
||||
"yargs": "^17.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
"bin": {
|
||||
"laconic": "bin/laconic"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"node_modules/@cerc-io/laconic-registry-cli/node_modules/argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"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"
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"node_modules/@cerc-io/laconic-registry-cli/node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"dev": true,
|
||||
"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"
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz",
|
||||
"integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@cerc-io/registry-sdk": {
|
||||
@ -5176,17 +5152,11 @@
|
||||
"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": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@ -6072,14 +6042,18 @@
|
||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/co": {
|
||||
@ -6794,19 +6768,12 @@
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"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": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
@ -7638,14 +7605,19 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||
"node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
@ -7705,20 +7677,11 @@
|
||||
"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": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
@ -8380,6 +8343,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@ -9017,6 +8981,19 @@
|
||||
"json5": "lib/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsx-ast-utils": {
|
||||
"version": "3.3.5",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
|
||||
@ -9484,6 +9461,16 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lodash-clean": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash-clean/-/lodash-clean-2.2.3.tgz",
|
||||
"integrity": "sha512-ioRhn/L0NNKq220nba58FPvjZ+bTdlUCb37+mhlDe4kzIzuPC/prUHLwDM9izeicr/rcnWrn0EanzNxhAbo8oA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
@ -11124,17 +11111,12 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"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": {
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
@ -11940,6 +11922,7 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
@ -11954,6 +11937,7 @@
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/string.prototype.includes": {
|
||||
@ -12067,6 +12051,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
@ -12518,14 +12503,14 @@
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unrs-resolver": {
|
||||
@ -12800,9 +12785,10 @@
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
@ -12810,7 +12796,10 @@
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
@ -12862,103 +12851,42 @@
|
||||
}
|
||||
},
|
||||
"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/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"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"
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/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/yargs/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/yargs/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/yargs/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": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
|
@ -6,7 +6,8 @@
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
"lint": "next lint",
|
||||
"laconic": "laconic registry -c deploy/config.yml"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cerc-io/registry-sdk": "^0.2.11",
|
||||
@ -28,6 +29,7 @@
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@cerc-io/laconic-registry-cli": "^0.2.9",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
|
@ -3,16 +3,16 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
import axios from 'axios';
|
||||
import assert from 'assert';
|
||||
|
||||
import { GasPrice } from '@cosmjs/stargate';
|
||||
import { Connection } from '@solana/web3.js';
|
||||
import { DENOM as ALNT_DENOM } from '@cerc-io/registry-sdk';
|
||||
|
||||
import { verifyUnusedSolanaPayment } from '@/utils/solana-verify';
|
||||
import { transferLNTTokens } from '@/services/laconic-transfer';
|
||||
import { getRegistry, getRegistryConfig } from '@/config';
|
||||
import { getRequiredTokenInfo, RequiredTokenInfo } from '@/services/jupiter-price';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED, SOLANA_GOR_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { SOLANA_GOR_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { PaymentMethod } from '@/types';
|
||||
import { getCostOfDeployment } from '@/services/registry';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED } from '@/utils/gorbagana';
|
||||
|
||||
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
|
||||
assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required when NAT GOR transfer is enabled');
|
||||
@ -215,14 +215,10 @@ export async function POST(request: NextRequest) {
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
// Verify Solana payment based on method
|
||||
console.log(`Step 0: Verifying Solana ${paymentMethod} payment...`);
|
||||
|
||||
|
||||
// Calculate expected token amount based on current price
|
||||
// Verify Solana payment
|
||||
console.log('Step 0: Verifying Solana token payment...');
|
||||
let requiredTokenInfo: RequiredTokenInfo;
|
||||
|
||||
const targetUsdAmount = parseFloat(process.env.NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD!);
|
||||
const targetUsdAmount = await getCostOfDeployment();
|
||||
const mintAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS!;
|
||||
|
||||
try {
|
||||
@ -284,9 +280,9 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
// Validate required environment variables for Solana payments
|
||||
const requiredEnvVars = [
|
||||
'REGISTRY_CHAIN_ID',
|
||||
'REGISTRY_GQL_ENDPOINT',
|
||||
'REGISTRY_RPC_ENDPOINT',
|
||||
'NEXT_PUBLIC_REGISTRY_CHAIN_ID',
|
||||
'NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT',
|
||||
'NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT',
|
||||
'REGISTRY_BOND_ID',
|
||||
'REGISTRY_AUTHORITY',
|
||||
'REGISTRY_USER_KEY', // This is the same as the prefilled account for LNT transfers
|
||||
@ -354,10 +350,6 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
const deployerLrn = process.env.DEPLOYER_LRN!;
|
||||
|
||||
// Create Registry client instance
|
||||
const gasPrice = GasPrice.fromString(config.fee.gasPrice + ALNT_DENOM);
|
||||
console.log('Using manual gas price:', gasPrice);
|
||||
|
||||
const registry = getRegistry()
|
||||
|
||||
// Create LRN for the application with commit hash
|
||||
|
@ -10,13 +10,21 @@ import { BackpackWalletName } from '@solana/wallet-adapter-backpack';
|
||||
import URLForm from '@/components/URLForm';
|
||||
import StatusDisplay from '@/components/StatusDisplay';
|
||||
import { createApplicationDeploymentRequest } from '@/services/registry';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED, PAYMENT_METHOD_LABELS } from '@/constants/payments';
|
||||
import { PAYMENT_METHOD_LABELS } from '@/constants/payments';
|
||||
import { usePaymentMethod } from '@/contexts/PaymentMethodContext';
|
||||
import { PaymentMethod } from '@/types';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED } from '@/utils/gorbagana';
|
||||
|
||||
// Dynamically import components to avoid SSR issues with browser APIs
|
||||
const PaymentModal = dynamic(() => import('@/components/PaymentModal'), { ssr: false });
|
||||
|
||||
// Use following curl request to get Gorbagana chain genesis hash:
|
||||
// curl https://rpc.gorbagana.wtf \
|
||||
// -X POST \
|
||||
// -H "Content-Type: application/json" \
|
||||
// --data '{"jsonrpc":"2.0","id":1,"method":"getGenesisHash"}'
|
||||
//
|
||||
// RPC endpoint reference: https://docs.gorbagana.wtf/testnet-v2-devnet.html
|
||||
const GORBAGANA_GENESIS_HASH = '533uBE9RRquhTBqEX58oV52FdTTsReMdAvaUvP6hNjsn';
|
||||
|
||||
export default function Home() {
|
||||
|
@ -9,8 +9,10 @@ import { useConnection, useWallet } from '@solana/wallet-adapter-react';
|
||||
import { sendSolanaPayment } from '@/services/solana';
|
||||
import { getRequiredTokenInfo, RequiredTokenInfo } from '@/services/jupiter-price';
|
||||
import { PaymentMethod, PaymentModalProps, PaymentRequest } from '@/types';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED, PAYMENT_METHOD_LABELS, SOLANA_GOR_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { PAYMENT_METHOD_LABELS, SOLANA_GOR_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { usePaymentMethod } from '@/contexts/PaymentMethodContext';
|
||||
import { getCostOfDeployment } from '@/services/registry';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED } from '@/utils/gorbagana';
|
||||
|
||||
assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required when NAT GOR transfer is enabled');
|
||||
|
||||
@ -23,28 +25,32 @@ export default function PaymentModal({
|
||||
onPaymentComplete,
|
||||
}: PaymentModalProps) {
|
||||
const { selectedPaymentMethod: paymentMethod } = usePaymentMethod();
|
||||
|
||||
const { connection: solanaConnection } = useConnection();
|
||||
const { wallet, publicKey } = useWallet();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const [tokenAmount, setTokenAmount] = useState<number>(0);
|
||||
const [tokenDecimals, setTokenDecimals] = useState<number>(6); // Default fallback
|
||||
const [loadingPrice, setLoadingPrice] = useState(false);
|
||||
const [loadingPrice, setLoadingPrice] = useState(true);
|
||||
const [deploymentCost, setDeploymentCost] = useState<number | null>(null);
|
||||
|
||||
const { wallet, publicKey } = useWallet();
|
||||
useEffect(() => {
|
||||
const getDeploymentCostInfo = async () => {
|
||||
const cost = await getCostOfDeployment();
|
||||
|
||||
setDeploymentCost(cost);
|
||||
}
|
||||
|
||||
getDeploymentCostInfo();
|
||||
}, []);
|
||||
|
||||
// Get configuration from environment variables
|
||||
const targetUsdAmount = parseFloat(process.env.NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD!);
|
||||
const mintAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS!;
|
||||
const tokenSymbol = process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL;
|
||||
|
||||
// Fetch payment amount based on USD price for both payment methods
|
||||
useEffect(() => {
|
||||
if (!isOpen || !paymentMethod) {
|
||||
setLoadingPrice(false);
|
||||
return;
|
||||
}
|
||||
if (!isOpen || !deploymentCost || !paymentMethod) return;
|
||||
|
||||
const fetchPaymentAmount = async () => {
|
||||
setLoadingPrice(true);
|
||||
@ -54,10 +60,10 @@ export default function PaymentModal({
|
||||
let requiredTokenInfo: RequiredTokenInfo
|
||||
if (paymentMethod === PaymentMethod.NAT_GOR) {
|
||||
// Fetch native GOR amount using solana GOR token price
|
||||
requiredTokenInfo = await getRequiredTokenInfo(targetUsdAmount, SOLANA_GOR_MINT_ADDRESS);
|
||||
requiredTokenInfo = await getRequiredTokenInfo(deploymentCost, SOLANA_GOR_MINT_ADDRESS);
|
||||
} else if (paymentMethod === PaymentMethod.SPL_TOKEN) {
|
||||
// Fetch SPL token amount using token mint price
|
||||
requiredTokenInfo = await getRequiredTokenInfo(targetUsdAmount, mintAddress);
|
||||
requiredTokenInfo = await getRequiredTokenInfo(deploymentCost, mintAddress);
|
||||
} else {
|
||||
setError('Invalid payment method');
|
||||
return;
|
||||
@ -74,7 +80,7 @@ export default function PaymentModal({
|
||||
};
|
||||
|
||||
fetchPaymentAmount();
|
||||
}, [isOpen, paymentMethod, targetUsdAmount, mintAddress]);
|
||||
}, [isOpen, paymentMethod, deploymentCost, mintAddress]);
|
||||
|
||||
// Initialize state when modal opens
|
||||
useEffect(() => {
|
||||
@ -184,19 +190,32 @@ export default function PaymentModal({
|
||||
</label>
|
||||
<div className="space-y-3">
|
||||
<div className="relative">
|
||||
<input
|
||||
type="text"
|
||||
value={targetUsdAmount}
|
||||
disabled={true}
|
||||
className="w-full p-3 pr-12 rounded-md"
|
||||
style={{
|
||||
background: 'var(--card-bg)',
|
||||
{loadingPrice ? (
|
||||
<div className="w-full p-3 rounded-md flex items-center" style={{
|
||||
background: 'var(--muted-light)',
|
||||
border: '1px solid var(--input-border)',
|
||||
color: 'var(--foreground)',
|
||||
opacity: '0.7'
|
||||
}}
|
||||
readOnly
|
||||
/>
|
||||
color: 'var(--muted)'
|
||||
}}>
|
||||
<svg className="animate-spin h-4 w-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
) : (
|
||||
<input
|
||||
type="text"
|
||||
value={`$${deploymentCost ? deploymentCost.toPrecision(2) : null}`}
|
||||
disabled={true}
|
||||
className="w-full p-3 pr-12 rounded-md"
|
||||
style={{
|
||||
background: 'var(--card-bg)',
|
||||
border: '1px solid var(--input-border)',
|
||||
color: 'var(--foreground)',
|
||||
opacity: '0.7'
|
||||
}}
|
||||
readOnly
|
||||
/>
|
||||
)}
|
||||
<div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
|
||||
<span className="text-sm font-medium" style={{ color: 'var(--muted)' }}>USD</span>
|
||||
</div>
|
||||
|
@ -1,30 +1,43 @@
|
||||
import { Registry, DENOM as ALNT_DENOM } from '@cerc-io/registry-sdk';
|
||||
import { GasPrice } from '@cosmjs/stargate';
|
||||
import { DENOM as ALNT_DENOM, Registry } from '@cerc-io/registry-sdk';
|
||||
|
||||
import { RegistryConfig } from '../types';
|
||||
import { GasPrice } from '@cosmjs/stargate';
|
||||
|
||||
let registryInstance: Registry | null = null;
|
||||
|
||||
|
||||
export const getRegistry = (): Registry => {
|
||||
if (!registryInstance) {
|
||||
const config = getRegistryConfig();
|
||||
const gasPrice = GasPrice.fromString(config.fee.gasPrice + ALNT_DENOM);
|
||||
const config = getClientRegistryConfig();
|
||||
const REGISTRY_GAS_PRICE = process.env.REGISTRY_GAS_PRICE;
|
||||
const gasPrice = REGISTRY_GAS_PRICE ? GasPrice.fromString( REGISTRY_GAS_PRICE + ALNT_DENOM) : undefined;
|
||||
|
||||
registryInstance = new Registry(
|
||||
config.gqlEndpoint,
|
||||
config.rpcEndpoint,
|
||||
{ chainId: config.chainId, gasPrice }
|
||||
{
|
||||
chainId: config.chainId,
|
||||
gasPrice,
|
||||
}
|
||||
);
|
||||
}
|
||||
return registryInstance;
|
||||
};
|
||||
|
||||
export const getClientRegistryConfig = () => {
|
||||
return {
|
||||
chainId: process.env.NEXT_PUBLIC_REGISTRY_CHAIN_ID!,
|
||||
rpcEndpoint: process.env.NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT!,
|
||||
gqlEndpoint: process.env.NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT!,
|
||||
};
|
||||
};
|
||||
|
||||
export const getRegistryConfig = (): RegistryConfig => {
|
||||
// Validate required environment variables
|
||||
const requiredEnvVars = [
|
||||
'REGISTRY_CHAIN_ID',
|
||||
'REGISTRY_GQL_ENDPOINT',
|
||||
'REGISTRY_RPC_ENDPOINT',
|
||||
'NEXT_PUBLIC_REGISTRY_CHAIN_ID',
|
||||
'NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT',
|
||||
'NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT',
|
||||
'REGISTRY_BOND_ID',
|
||||
'REGISTRY_AUTHORITY',
|
||||
'REGISTRY_USER_KEY'
|
||||
@ -37,14 +50,11 @@ export const getRegistryConfig = (): RegistryConfig => {
|
||||
}
|
||||
|
||||
return {
|
||||
chainId: process.env.REGISTRY_CHAIN_ID!,
|
||||
rpcEndpoint: process.env.REGISTRY_RPC_ENDPOINT!,
|
||||
gqlEndpoint: process.env.REGISTRY_GQL_ENDPOINT!,
|
||||
chainId: process.env.NEXT_PUBLIC_REGISTRY_CHAIN_ID!,
|
||||
rpcEndpoint: process.env.NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT!,
|
||||
gqlEndpoint: process.env.NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT!,
|
||||
bondId: process.env.REGISTRY_BOND_ID!,
|
||||
authority: process.env.REGISTRY_AUTHORITY!,
|
||||
privateKey: process.env.REGISTRY_USER_KEY!,
|
||||
fee: {
|
||||
gasPrice: process.env.REGISTRY_GAS_PRICE || '0.001',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -7,5 +7,3 @@ export const PAYMENT_METHOD_LABELS: Record<PaymentMethod, string> = {
|
||||
};
|
||||
|
||||
export const SOLANA_GOR_MINT_ADDRESS = '71Jvq4Epe2FCJ7JFSF7jLXdNk1Wy4Bhqd9iL6bEFELvg';
|
||||
|
||||
export const IS_NAT_GOR_TRANSFER_ENABLED = process.env.NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER === "true";
|
||||
|
@ -86,7 +86,6 @@ const getAccount = async (accountPrivateKey: string): Promise<Account> => {
|
||||
return account;
|
||||
}
|
||||
|
||||
|
||||
const sendTokensToAccount = async (
|
||||
senderPrivateKey: string,
|
||||
receiverAddress: string,
|
||||
|
@ -1,5 +1,13 @@
|
||||
import { CreateRecordResponse } from '../types';
|
||||
import { PaymentMethod } from '../types';
|
||||
import assert from 'assert';
|
||||
|
||||
import { getRegistry } from '@/config';
|
||||
import { CreateRecordResponse, PricingRecordAttributes, PaymentMethod } from '../types';
|
||||
|
||||
assert(process.env.NEXT_PUBLIC_DEPLOYMENT_COST_LRN, 'DEPLOYMENT_COST_LRN is required');
|
||||
assert(process.env.NEXT_PUBLIC_ALNT_COST_LRN, 'ALNT_COST_LRN is required');
|
||||
|
||||
const DEPLOYMENT_COST_LRN = process.env.NEXT_PUBLIC_DEPLOYMENT_COST_LRN;
|
||||
const ALNT_COST_LRN = process.env.NEXT_PUBLIC_ALNT_COST_LRN;
|
||||
|
||||
export const createApplicationDeploymentRequest = async (
|
||||
url: string,
|
||||
@ -51,3 +59,33 @@ export const createApplicationDeploymentRequest = async (
|
||||
}
|
||||
};
|
||||
|
||||
const resolvePricingRecordLrns = async (lrns: string[]): Promise<PricingRecordAttributes[]> => {
|
||||
const registry = getRegistry();
|
||||
const result = await registry.resolveNames(lrns);
|
||||
const pricingRecordsAttributes: PricingRecordAttributes[] = result.map((record: any) => {
|
||||
return record.attributes
|
||||
});
|
||||
|
||||
return pricingRecordsAttributes;
|
||||
};
|
||||
|
||||
export const getCostOfDeployment = async (): Promise<number> => {
|
||||
const resolvedRecords = await resolvePricingRecordLrns([ALNT_COST_LRN, DEPLOYMENT_COST_LRN]);
|
||||
console.log('resolvedRecords:', resolvedRecords);
|
||||
|
||||
// Find the ALNT price record (USD per ALNT)
|
||||
const alntPriceRecord = resolvedRecords[0];
|
||||
// Find the deployment cost record (ALNT cost for webapp-deployment)
|
||||
const deploymentCostRecord = resolvedRecords[1];
|
||||
|
||||
if (!alntPriceRecord || !deploymentCostRecord) {
|
||||
throw new Error('Required pricing records not found');
|
||||
}
|
||||
|
||||
// Convert strings to numbers for calculation
|
||||
const alntPriceUsd = parseFloat(alntPriceRecord.amount); // USD per ALNT
|
||||
const deploymentCostAlnt = parseFloat(deploymentCostRecord.amount); // ALNT required
|
||||
|
||||
// Calculate deployment cost in USD: (ALNT required) * (USD per ALNT)
|
||||
return deploymentCostAlnt * alntPriceUsd;
|
||||
}
|
||||
|
@ -10,9 +10,6 @@ export interface RegistryConfig {
|
||||
bondId: string;
|
||||
authority: string;
|
||||
privateKey: string;
|
||||
fee: {
|
||||
gasPrice: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateRecordResponse {
|
||||
@ -53,3 +50,11 @@ export interface LaconicTransferResult {
|
||||
transactionHash?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface PricingRecordAttributes {
|
||||
amount: string;
|
||||
currency: string;
|
||||
for: string;
|
||||
type: string;
|
||||
version: string;
|
||||
}
|
||||
|
1
src/utils/gorbagana.ts
Normal file
1
src/utils/gorbagana.ts
Normal file
@ -0,0 +1 @@
|
||||
export const IS_NAT_GOR_TRANSFER_ENABLED = process.env.NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER === "true";
|
Loading…
Reference in New Issue
Block a user