From 155fecc060df527d677e4a3e949ccf35564c0680 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 22 Jul 2025 11:32:19 +0530 Subject: [PATCH 01/19] Add steps to publish deployment cost record --- deploy/deployment-cost.yml | 5 ++ deploy/publish-deployment-cost.md | 91 +++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 deploy/deployment-cost.yml create mode 100644 deploy/publish-deployment-cost.md diff --git a/deploy/deployment-cost.yml b/deploy/deployment-cost.yml new file mode 100644 index 0000000..bfbf734 --- /dev/null +++ b/deploy/deployment-cost.yml @@ -0,0 +1,5 @@ +record: + type: ApplicationDeploymentCostRecord + amount: "5" + currency: "USD" + version: 1.0.0 diff --git a/deploy/publish-deployment-cost.md b/deploy/publish-deployment-cost.md new file mode 100644 index 0000000..7078070 --- /dev/null +++ b/deploy/publish-deployment-cost.md @@ -0,0 +1,91 @@ +# publish-deployment-cost + +## Prerequisites + +- [laconic-registry-cli](https://git.vdb.to/cerc-io/laconic-registry-cli#install) + +## Setup + +- Go to `deploy` directory: + + ```bash + cd deploy + ``` + +- Configure `userKey` in the [registry CLI config](./config.yml): + + ```bash + nano config.yml + ``` + +- Update `cost` and `currency` in [deployment-cost.yml](./deployment-cost.yml) file as required: + + ```bash + nano deployment-cost.yml + ``` + +## Create Bond + +- Create bond: + + ```bash + laconic registry bond create --type alnt --quantity 1000 + ``` + +- Get bond info: + +```bash + laconic registry bond get --id +``` + +## Publish Record + +- Publish a record + + ```bash + laconic registry record publish --filename deployment-cost.yml --bond-id --gas 250000 --fees 250alnt + + { id: 'bafyreic3auqajv...' } + ``` + +- Get record info: + + ```bash + laconic registry record get --id + ``` + +## Reserve a New Authority + +- Reserve authority: + + ```bash + laconic registry authority reserve laconic + ``` + +- Check authority info: + + ```bash + laconic registry authority whois laconic + ``` + + - Note down auction ID from authority info as it is required in next steps + +- Get auction info: + + ```bash + laconic registry auction get + ``` + +- Commit an auction bid: + + ```bash + laconic registry auction bid commit 25000000 alnt + + Reveal file: ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + ``` + +- Reveal bid: + + ```bash + laconic registry auction bid reveal ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + ``` -- 2.45.2 From 5d253615fb6da93996418680de86e75a847b9b17 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 22 Jul 2025 14:11:02 +0530 Subject: [PATCH 02/19] Update record type --- deploy/README.md | 3 ++- deploy/{deployment-cost.yml => pricing.yml} | 3 ++- ...ish-deployment-cost.md => publish-pricing.md} | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) rename deploy/{deployment-cost.yml => pricing.yml} (53%) rename deploy/{publish-deployment-cost.md => publish-pricing.md} (79%) diff --git a/deploy/README.md b/deploy/README.md index 5a22711..be5ed5f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -48,6 +48,7 @@ ### gor-deploy * Deploy `gor-deploy` App: + ```bash # In gor-deploy/deploy dir docker run -it \ @@ -61,7 +62,7 @@ * Visit deployed app: -### remove deployment +### Remove deployment * Remove deployment: diff --git a/deploy/deployment-cost.yml b/deploy/pricing.yml similarity index 53% rename from deploy/deployment-cost.yml rename to deploy/pricing.yml index bfbf734..3bf6bda 100644 --- a/deploy/deployment-cost.yml +++ b/deploy/pricing.yml @@ -1,5 +1,6 @@ record: - type: ApplicationDeploymentCostRecord + type: PricingRecord + for: "webapp-deployment" amount: "5" currency: "USD" version: 1.0.0 diff --git a/deploy/publish-deployment-cost.md b/deploy/publish-pricing.md similarity index 79% rename from deploy/publish-deployment-cost.md rename to deploy/publish-pricing.md index 7078070..594fef9 100644 --- a/deploy/publish-deployment-cost.md +++ b/deploy/publish-pricing.md @@ -1,4 +1,4 @@ -# publish-deployment-cost +# publish-pricing ## Prerequisites @@ -18,10 +18,10 @@ nano config.yml ``` -- Update `cost` and `currency` in [deployment-cost.yml](./deployment-cost.yml) file as required: +- Update `cost` and `currency` in [pricing.yml](./pricing.yml) file as required: ```bash - nano deployment-cost.yml + nano pricing.yml ``` ## Create Bond @@ -43,7 +43,7 @@ - Publish a record ```bash - laconic registry record publish --filename deployment-cost.yml --bond-id --gas 250000 --fees 250alnt + laconic registry record publish --filename pricing.yml --bond-id --gas 250000 --fees 250alnt { id: 'bafyreic3auqajv...' } ``` @@ -89,3 +89,11 @@ ```bash laconic registry auction bid reveal ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json ``` + +## Set Record Name + +- Set name: + + ```bash + laconic registry name set lrn:///pricing/webapp-deployment + ``` -- 2.45.2 From 64b6b1082d1030e99050b634665bdc45bb03a351 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 22 Jul 2025 15:31:34 +0530 Subject: [PATCH 03/19] Update steps to publish pricing deployment record --- deploy/publish-pricing.md | 46 +++--- package-lock.json | 310 +++++++++++++++----------------------- package.json | 4 +- 3 files changed, 147 insertions(+), 213 deletions(-) diff --git a/deploy/publish-pricing.md b/deploy/publish-pricing.md index 594fef9..a46470e 100644 --- a/deploy/publish-pricing.md +++ b/deploy/publish-pricing.md @@ -2,16 +2,14 @@ ## Prerequisites -- [laconic-registry-cli](https://git.vdb.to/cerc-io/laconic-registry-cli#install) - -## Setup - -- Go to `deploy` directory: +- Install packages: ```bash - cd deploy + npm install ``` +## Setup + - Configure `userKey` in the [registry CLI config](./config.yml): ```bash @@ -29,43 +27,41 @@ - Create bond: ```bash - laconic registry bond create --type alnt --quantity 1000 + npm run laconic bond create --type alnt --quantity 100000000 ``` - Get bond info: -```bash - laconic registry bond get --id -``` + ```bash + npm run laconic bond get --id + ``` ## Publish Record - Publish a record ```bash - laconic registry record publish --filename pricing.yml --bond-id --gas 250000 --fees 250alnt - - { id: 'bafyreic3auqajv...' } + npm run laconic record publish --filename pricing.yml --bond-id --gas 250000 --fees 250000alnt ``` - Get record info: ```bash - laconic registry record get --id + npm run laconic record get --id ``` -## Reserve a New Authority +## Reserve a New Authority (optional) - Reserve authority: ```bash - laconic registry authority reserve laconic + npm run laconic authority reserve laconic ``` - Check authority info: ```bash - laconic registry authority whois laconic + npm run laconic authority whois laconic ``` - Note down auction ID from authority info as it is required in next steps @@ -73,13 +69,13 @@ - Get auction info: ```bash - laconic registry auction get + npm run laconic auction get ``` - Commit an auction bid: ```bash - laconic registry auction bid commit 25000000 alnt + npm run laconic auction bid commit 25000000 alnt Reveal file: ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json ``` @@ -87,7 +83,15 @@ - Reveal bid: ```bash - laconic registry auction bid reveal ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + npm run laconic auction bid reveal ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + ``` + +## Set Authority Bond + +- Set authority bond after winning auction: + + ```bash + npm run laconic authority bond set laconic ``` ## Set Record Name @@ -95,5 +99,5 @@ - Set name: ```bash - laconic registry name set lrn:///pricing/webapp-deployment + npm run laconic name set lrn:///pricing/webapp-deployment ``` diff --git a/package-lock.json b/package-lock.json index 0b0c62b..fe3efda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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": { diff --git a/package.json b/package.json index 24ac37b..223eb09 100644 --- a/package.json +++ b/package.json @@ -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", -- 2.45.2 From 6c2ee093a272ba4c98cb15aec6a3b20604929162 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 22 Jul 2025 17:11:39 +0530 Subject: [PATCH 04/19] Take deployment cost from published pricing record --- .env.example | 11 +++-- CLAUDE.md | 6 +-- src/app/api/registry/route.ts | 6 +-- src/components/PaymentModal.tsx | 74 +++++++++++++++++++++++++++------ src/config/index.ts | 12 +++--- 5 files changed, 78 insertions(+), 31 deletions(-) diff --git a/.env.example b/.env.example index fb8fd7a..81a004c 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -# 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 @@ -17,12 +17,11 @@ 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_PRICING_RECORD_LRN= REGISTRY_GAS_PRICE=0.001 REGISTRY_BOND_ID= REGISTRY_AUTHORITY= diff --git a/CLAUDE.md b/CLAUDE.md index dc64720..10e3e28 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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= REGISTRY_AUTHORITY= REGISTRY_USER_KEY= diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index 8e2b74c..1f14775 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -284,9 +284,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 diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index 9bcd753..bcec2f4 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -1,11 +1,12 @@ 'use client'; -import { useCallback, useState, useEffect } from 'react'; +import { useCallback, useState, useEffect, useMemo } from 'react'; import assert from 'assert'; import { Connection } from '@solana/web3.js'; import { useConnection, useWallet } from '@solana/wallet-adapter-react'; +import { getRegistry } from '@/config'; import { sendSolanaPayment } from '@/services/solana'; import { getRequiredTokenInfo, RequiredTokenInfo } from '@/services/jupiter-price'; import { PaymentMethod, PaymentModalProps, PaymentRequest } from '@/types'; @@ -16,6 +17,26 @@ assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL const GORBAGANA_RPC_URL = process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL; +assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); +assert(process.env.NEXT_PUBLIC_PRICING_RECORD_LRN, 'DEPLOYMENT_RECORD_LRN is required'); + +const PRICING_RECORD_LRN = process.env.NEXT_PUBLIC_PRICING_RECORD_LRN; +const SUPPORTED_CURRENCY = "USD"; +const VALID_PRICING_RECORD_TYPE = "webapp-deployment"; + +interface DeploymentCostInfo { + amount: string; + currency: string; +} + +interface PricingRecordAttributes { + amount: string; + currency: string; + for: string; + type: string; + version: string; +} + export default function PaymentModal({ isOpen, onClose, @@ -23,28 +44,55 @@ 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(0); const [tokenDecimals, setTokenDecimals] = useState(6); // Default fallback - const [loadingPrice, setLoadingPrice] = useState(false); + const [loadingPrice, setLoadingPrice] = useState(true); + const [deploymentCostInfo, setDeploymentCostInfo] = useState(); - const { wallet, publicKey } = useWallet(); + useEffect(() => { + const registry = getRegistry(); + + const resolveDeploymentCostInfo = async () => { + const result = await registry.resolveNames([PRICING_RECORD_LRN!]) + const PricingRecordAttributes: PricingRecordAttributes = result[0].attributes; + + if (PricingRecordAttributes.type !== VALID_PRICING_RECORD_TYPE) { + throw new Error(`Incorrect pricing record type: ${PricingRecordAttributes.type}. Please provide correct pricing record lrn`) + } + + if (PricingRecordAttributes.currency !== SUPPORTED_CURRENCY) { + throw new Error(`Unsupported currency found in pricing record: ${PricingRecordAttributes.currency}`) + } + + setDeploymentCostInfo({ + amount: PricingRecordAttributes.amount, + currency:PricingRecordAttributes.currency + }) + } + + resolveDeploymentCostInfo(); + }, []); // Get configuration from environment variables - const targetUsdAmount = parseFloat(process.env.NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD!); + const deploymentCost = useMemo(() => { + if (!deploymentCostInfo) { + return; + } + + return parseInt(deploymentCostInfo.amount, 10); + }, [deploymentCostInfo]) + 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 +102,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 +122,7 @@ export default function PaymentModal({ }; fetchPaymentAmount(); - }, [isOpen, paymentMethod, targetUsdAmount, mintAddress]); + }, [isOpen, paymentMethod, deploymentCost, mintAddress]); // Initialize state when modal opens useEffect(() => { @@ -186,7 +234,7 @@ export default function PaymentModal({
{ 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,9 +37,9 @@ 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!, -- 2.45.2 From 9633d49374b31d4f54e7a67c60fe5478d7b6b3d6 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 22 Jul 2025 17:38:05 +0530 Subject: [PATCH 05/19] Update method to get registry config on client side --- .env.example | 2 +- src/components/PaymentModal.tsx | 4 ++-- src/config/index.ts | 13 ++++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 81a004c..51a6106 100644 --- a/.env.example +++ b/.env.example @@ -21,8 +21,8 @@ NEXT_PUBLIC_EXAMPLE_URL=https://git.vdb.to/cerc-io/test-progressive-web-app 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_REGISTRY_GAS_PRICE=0.001 NEXT_PUBLIC_PRICING_RECORD_LRN= -REGISTRY_GAS_PRICE=0.001 REGISTRY_BOND_ID= REGISTRY_AUTHORITY= REGISTRY_USER_KEY= diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index bcec2f4..cb00475 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -22,7 +22,7 @@ assert(process.env.NEXT_PUBLIC_PRICING_RECORD_LRN, 'DEPLOYMENT_RECORD_LRN is req const PRICING_RECORD_LRN = process.env.NEXT_PUBLIC_PRICING_RECORD_LRN; const SUPPORTED_CURRENCY = "USD"; -const VALID_PRICING_RECORD_TYPE = "webapp-deployment"; +const VALID_PRICING_RECORD_FOR = "webapp-deployment"; interface DeploymentCostInfo { amount: string; @@ -61,7 +61,7 @@ export default function PaymentModal({ const result = await registry.resolveNames([PRICING_RECORD_LRN!]) const PricingRecordAttributes: PricingRecordAttributes = result[0].attributes; - if (PricingRecordAttributes.type !== VALID_PRICING_RECORD_TYPE) { + if (PricingRecordAttributes.for !== VALID_PRICING_RECORD_FOR) { throw new Error(`Incorrect pricing record type: ${PricingRecordAttributes.type}. Please provide correct pricing record lrn`) } diff --git a/src/config/index.ts b/src/config/index.ts index 6ce836a..9afd1ea 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -7,7 +7,7 @@ let registryInstance: Registry | null = null; export const getRegistry = (): Registry => { if (!registryInstance) { - const config = getRegistryConfig(); + const config = getClientRegistryConfig(); const gasPrice = GasPrice.fromString(config.fee.gasPrice + ALNT_DENOM); registryInstance = new Registry( @@ -19,6 +19,17 @@ export const getRegistry = (): Registry => { 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!, + fee: { + gasPrice: process.env.NEXT_PUBLIC_REGISTRY_GAS_PRICE || '0.001', + }, + }; +}; + export const getRegistryConfig = (): RegistryConfig => { // Validate required environment variables const requiredEnvVars = [ -- 2.45.2 From 3b570dbeb91184883fa69c4838d8ae4cba685ab4 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 22 Jul 2025 18:15:40 +0530 Subject: [PATCH 06/19] Refactor method to resolve pricing record lrn --- .env.example | 1 - src/app/api/registry/route.ts | 12 +++++------ src/components/PaymentModal.tsx | 35 ++++++--------------------------- src/config/index.ts | 2 +- src/services/registry.ts | 28 ++++++++++++++++++++++++-- src/types/index.ts | 8 ++++++++ 6 files changed, 46 insertions(+), 40 deletions(-) diff --git a/.env.example b/.env.example index 51a6106..df4e429 100644 --- a/.env.example +++ b/.env.example @@ -5,7 +5,6 @@ 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 diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index 1f14775..a65c5b8 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -13,6 +13,7 @@ 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 { PaymentMethod } from '@/types'; +import { resolvePricingRecordLrn } from '@/services/registry'; 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 +216,11 @@ 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 pricingRecordAttributes = await resolvePricingRecordLrn(); + const targetUsdAmount = parseInt(pricingRecordAttributes.amount, 10); const mintAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS!; try { diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index cb00475..47be3e8 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -6,12 +6,12 @@ import assert from 'assert'; import { Connection } from '@solana/web3.js'; import { useConnection, useWallet } from '@solana/wallet-adapter-react'; -import { getRegistry } from '@/config'; 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 { usePaymentMethod } from '@/contexts/PaymentMethodContext'; +import { resolvePricingRecordLrn } from '@/services/registry'; assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required when NAT GOR transfer is enabled'); @@ -20,23 +20,11 @@ const GORBAGANA_RPC_URL = process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL; assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); assert(process.env.NEXT_PUBLIC_PRICING_RECORD_LRN, 'DEPLOYMENT_RECORD_LRN is required'); -const PRICING_RECORD_LRN = process.env.NEXT_PUBLIC_PRICING_RECORD_LRN; -const SUPPORTED_CURRENCY = "USD"; -const VALID_PRICING_RECORD_FOR = "webapp-deployment"; - interface DeploymentCostInfo { amount: string; currency: string; } -interface PricingRecordAttributes { - amount: string; - currency: string; - for: string; - type: string; - version: string; -} - export default function PaymentModal({ isOpen, onClose, @@ -55,27 +43,16 @@ export default function PaymentModal({ const [deploymentCostInfo, setDeploymentCostInfo] = useState(); useEffect(() => { - const registry = getRegistry(); - - const resolveDeploymentCostInfo = async () => { - const result = await registry.resolveNames([PRICING_RECORD_LRN!]) - const PricingRecordAttributes: PricingRecordAttributes = result[0].attributes; - - if (PricingRecordAttributes.for !== VALID_PRICING_RECORD_FOR) { - throw new Error(`Incorrect pricing record type: ${PricingRecordAttributes.type}. Please provide correct pricing record lrn`) - } - - if (PricingRecordAttributes.currency !== SUPPORTED_CURRENCY) { - throw new Error(`Unsupported currency found in pricing record: ${PricingRecordAttributes.currency}`) - } + const getDeploymentCostInfo = async () => { + const pricingRecordAttributes = await resolvePricingRecordLrn(); setDeploymentCostInfo({ - amount: PricingRecordAttributes.amount, - currency:PricingRecordAttributes.currency + amount: pricingRecordAttributes.amount, + currency:pricingRecordAttributes.currency }) } - resolveDeploymentCostInfo(); + getDeploymentCostInfo(); }, []); // Get configuration from environment variables diff --git a/src/config/index.ts b/src/config/index.ts index 9afd1ea..0a9954b 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -25,7 +25,7 @@ export const getClientRegistryConfig = () => { rpcEndpoint: process.env.NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT!, gqlEndpoint: process.env.NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT!, fee: { - gasPrice: process.env.NEXT_PUBLIC_REGISTRY_GAS_PRICE || '0.001', + gasPrice: process.env.NEXT_PUBLIC_REGISTRY_GAS_PRICE!, }, }; }; diff --git a/src/services/registry.ts b/src/services/registry.ts index 7b65499..75a6b6a 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -1,5 +1,14 @@ -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_PRICING_RECORD_LRN, 'DEPLOYMENT_RECORD_LRN is required'); +const PRICING_RECORD_LRN = process.env.NEXT_PUBLIC_PRICING_RECORD_LRN; + +const SUPPORTED_CURRENCY = "USD"; +const VALID_PRICING_RECORD_FOR = "webapp-deployment"; + export const createApplicationDeploymentRequest = async ( url: string, @@ -51,3 +60,18 @@ export const createApplicationDeploymentRequest = async ( } }; +export const resolvePricingRecordLrn = async (): Promise => { + const registry = getRegistry(); + const result = await registry.resolveNames([PRICING_RECORD_LRN]) + const pricingRecordAttributes: PricingRecordAttributes = result[0].attributes; + + if (pricingRecordAttributes.for !== VALID_PRICING_RECORD_FOR) { + throw new Error(`Incorrect pricing record type: ${pricingRecordAttributes.type}. Please provide correct pricing record lrn`) + } + + if (pricingRecordAttributes.currency !== SUPPORTED_CURRENCY) { + throw new Error(`Unsupported currency found in pricing record: ${pricingRecordAttributes.currency}`) + } + + return pricingRecordAttributes; +} diff --git a/src/types/index.ts b/src/types/index.ts index 86203f5..9dab16e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -53,3 +53,11 @@ export interface LaconicTransferResult { transactionHash?: string; error?: string; } + +export interface PricingRecordAttributes { + amount: string; + currency: string; + for: string; + type: string; + version: string; +} -- 2.45.2 From 4823ca37cfb032b3cbcf150c34a8772e2581eff5 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 22 Jul 2025 18:26:53 +0530 Subject: [PATCH 07/19] Open jupiter price information in new tab --- src/services/laconic-transfer.ts | 1 - src/services/registry.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/laconic-transfer.ts b/src/services/laconic-transfer.ts index 1a59d05..3d858b4 100644 --- a/src/services/laconic-transfer.ts +++ b/src/services/laconic-transfer.ts @@ -86,7 +86,6 @@ const getAccount = async (accountPrivateKey: string): Promise => { return account; } - const sendTokensToAccount = async ( senderPrivateKey: string, receiverAddress: string, diff --git a/src/services/registry.ts b/src/services/registry.ts index 75a6b6a..861612b 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -62,7 +62,7 @@ export const createApplicationDeploymentRequest = async ( export const resolvePricingRecordLrn = async (): Promise => { const registry = getRegistry(); - const result = await registry.resolveNames([PRICING_RECORD_LRN]) + const result = await registry.resolveNames([PRICING_RECORD_LRN]); const pricingRecordAttributes: PricingRecordAttributes = result[0].attributes; if (pricingRecordAttributes.for !== VALID_PRICING_RECORD_FOR) { -- 2.45.2 From 00cfd280c095273a0d3d5e045adcd1ae899ea1fc Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 24 Jul 2025 10:03:42 +0530 Subject: [PATCH 08/19] Update readme to publish required records --- deploy/pricing.yml | 6 +-- deploy/publish-pricing.md | 86 +++++++++++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 24 deletions(-) diff --git a/deploy/pricing.yml b/deploy/pricing.yml index 3bf6bda..8fe991e 100644 --- a/deploy/pricing.yml +++ b/deploy/pricing.yml @@ -1,6 +1,6 @@ record: type: PricingRecord - for: "webapp-deployment" - amount: "5" - currency: "USD" + for: "" + amount: "" + currency: "" version: 1.0.0 diff --git a/deploy/publish-pricing.md b/deploy/publish-pricing.md index a46470e..44eb3c1 100644 --- a/deploy/publish-pricing.md +++ b/deploy/publish-pricing.md @@ -16,38 +16,66 @@ nano config.yml ``` -- Update `cost` and `currency` in [pricing.yml](./pricing.yml) file as required: - - ```bash - nano pricing.yml - ``` - ## Create Bond - Create bond: ```bash - npm run laconic bond create --type alnt --quantity 100000000 + npm run laconic -- bond create --type alnt --quantity 100000000 ``` - Get bond info: ```bash - npm run laconic bond get --id + npm run laconic -- bond get --id ``` -## Publish Record +## Publish Record for Cost of alnt -- Publish a record +- Update `for`, `cost` and `currency` fields in [pricing.yml](./pricing.yml) file: ```bash - npm run laconic record publish --filename pricing.yml --bond-id --gas 250000 --fees 250000alnt + ... + for: "alnt" + amount: "0.000385802" + currency: "USD" + ... + ``` + +- Publish the record: + + ```bash + npm run laconic -- record publish --filename deploy/pricing.yml --bond-id --gas 250000 --fees 250000alnt ``` - Get record info: ```bash - npm run laconic record get --id + npm run laconic -- record get --id + ``` + +## Publish Record for Cost of Deployment + +- Update `for`, `cost` and `currency` fields in [pricing.yml](./pricing.yml) file: + + ```bash + ... + for: "webapp-deployment" + amount: "12960" + currency: "alnt" + ... + ``` + +- Publish the record: + + ```bash + npm run laconic -- record publish --filename deploy/pricing.yml --bond-id --gas 250000 --fees 250000alnt + ``` + +- Get record info: + + ```bash + npm run laconic -- record get --id ``` ## Reserve a New Authority (optional) @@ -55,13 +83,13 @@ - Reserve authority: ```bash - npm run laconic authority reserve laconic + npm run laconic -- authority reserve laconic ``` - Check authority info: ```bash - npm run laconic authority whois laconic + npm run laconic -- authority whois laconic ``` - Note down auction ID from authority info as it is required in next steps @@ -69,13 +97,13 @@ - Get auction info: ```bash - npm run laconic auction get + npm run laconic -- auction get ``` - Commit an auction bid: ```bash - npm run laconic auction bid commit 25000000 alnt + npm run laconic -- auction bid commit 25000000 alnt Reveal file: ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json ``` @@ -83,21 +111,37 @@ - Reveal bid: ```bash - npm run laconic auction bid reveal ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + npm run laconic -- auction bid reveal ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json ``` -## Set Authority Bond +### Set Authority Bond - Set authority bond after winning auction: ```bash - npm run laconic authority bond set laconic + npm run laconic -- authority bond set laconic ``` ## Set Record Name -- Set name: +NOTE: To set record name an authority with an authority bond is required + +- Set record name for cost of alnt record ```bash - npm run laconic name set lrn:///pricing/webapp-deployment + npm run laconic -- name set lrn:///pricing/alnt + ``` + +- Set record name for cost of deployment record + + ```bash + npm run laconic -- name set lrn:///pricing/webapp-deployment + ``` + +## Delete Record Name + +- Delete record name: + + ```bash + npm run laconic -- name delete ``` -- 2.45.2 From aa1f6e461afae434cc45d46512410c0d59cd8da8 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 24 Jul 2025 11:02:24 +0530 Subject: [PATCH 09/19] Get cost of deployment using newly published records --- .env.example | 3 ++- src/app/api/registry/route.ts | 5 ++-- src/components/PaymentModal.tsx | 27 ++++--------------- src/services/registry.ts | 47 +++++++++++++++++++++++---------- 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/.env.example b/.env.example index df4e429..df7daba 100644 --- a/.env.example +++ b/.env.example @@ -21,7 +21,8 @@ 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_REGISTRY_GAS_PRICE=0.001 -NEXT_PUBLIC_PRICING_RECORD_LRN= +NEXT_PUBLIC_ALNT_COST_LRN= +NEXT_PUBLIC_DEPLOYMENT_COST_LRN= REGISTRY_BOND_ID= REGISTRY_AUTHORITY= REGISTRY_USER_KEY= diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index a65c5b8..7ec48f0 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -13,7 +13,7 @@ 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 { PaymentMethod } from '@/types'; -import { resolvePricingRecordLrn } from '@/services/registry'; +import { getCostOfDeployment } from '@/services/registry'; 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'); @@ -219,8 +219,7 @@ export async function POST(request: NextRequest) { // Verify Solana payment console.log('Step 0: Verifying Solana token payment...'); let requiredTokenInfo: RequiredTokenInfo; - const pricingRecordAttributes = await resolvePricingRecordLrn(); - const targetUsdAmount = parseInt(pricingRecordAttributes.amount, 10); + const targetUsdAmount = await getCostOfDeployment(); const mintAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS!; try { diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index 47be3e8..be9e330 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useCallback, useState, useEffect, useMemo } from 'react'; +import { useCallback, useState, useEffect } from 'react'; import assert from 'assert'; import { Connection } from '@solana/web3.js'; @@ -11,7 +11,7 @@ import { getRequiredTokenInfo, RequiredTokenInfo } from '@/services/jupiter-pric import { PaymentMethod, PaymentModalProps, PaymentRequest } from '@/types'; import { IS_NAT_GOR_TRANSFER_ENABLED, PAYMENT_METHOD_LABELS, SOLANA_GOR_MINT_ADDRESS } from '@/constants/payments'; import { usePaymentMethod } from '@/contexts/PaymentMethodContext'; -import { resolvePricingRecordLrn } from '@/services/registry'; +import { getCostOfDeployment } from '@/services/registry'; assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required when NAT GOR transfer is enabled'); @@ -20,11 +20,6 @@ const GORBAGANA_RPC_URL = process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL; assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); assert(process.env.NEXT_PUBLIC_PRICING_RECORD_LRN, 'DEPLOYMENT_RECORD_LRN is required'); -interface DeploymentCostInfo { - amount: string; - currency: string; -} - export default function PaymentModal({ isOpen, onClose, @@ -40,30 +35,18 @@ export default function PaymentModal({ const [tokenAmount, setTokenAmount] = useState(0); const [tokenDecimals, setTokenDecimals] = useState(6); // Default fallback const [loadingPrice, setLoadingPrice] = useState(true); - const [deploymentCostInfo, setDeploymentCostInfo] = useState(); + const [deploymentCost, setDeploymentCost] = useState(null); useEffect(() => { const getDeploymentCostInfo = async () => { - const pricingRecordAttributes = await resolvePricingRecordLrn(); + const cost = await getCostOfDeployment(); - setDeploymentCostInfo({ - amount: pricingRecordAttributes.amount, - currency:pricingRecordAttributes.currency - }) + setDeploymentCost(cost); } getDeploymentCostInfo(); }, []); - // Get configuration from environment variables - const deploymentCost = useMemo(() => { - if (!deploymentCostInfo) { - return; - } - - return parseInt(deploymentCostInfo.amount, 10); - }, [deploymentCostInfo]) - const mintAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS!; const tokenSymbol = process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL; diff --git a/src/services/registry.ts b/src/services/registry.ts index 861612b..4962d89 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -3,12 +3,13 @@ import assert from 'assert'; import { getRegistry } from '@/config'; import { CreateRecordResponse, PricingRecordAttributes, PaymentMethod } from '../types'; -assert(process.env.NEXT_PUBLIC_PRICING_RECORD_LRN, 'DEPLOYMENT_RECORD_LRN is required'); -const PRICING_RECORD_LRN = process.env.NEXT_PUBLIC_PRICING_RECORD_LRN; - -const SUPPORTED_CURRENCY = "USD"; -const VALID_PRICING_RECORD_FOR = "webapp-deployment"; +assert(process.env.NEXT_PUBLIC_DEPLOYMENT_COST_LRN, 'DEPLOYMENT_RECORD_LRN is required'); +assert(process.env.NEXT_PUBLIC_ALNT_COST_LRN, 'DEPLOYMENT_RECORD_LRN is required'); +const DEPLOYMENT_COST_LRN = process.env.NEXT_PUBLIC_DEPLOYMENT_COST_LRN; +const DEPLOYMENT = 'webapp-deployment'; +const ALNT_COST_LRN = process.env.NEXT_PUBLIC_ALNT_COST_LRN; +const ALNT = 'alnt'; export const createApplicationDeploymentRequest = async ( url: string, @@ -60,18 +61,36 @@ export const createApplicationDeploymentRequest = async ( } }; -export const resolvePricingRecordLrn = async (): Promise => { +const resolvePricingRecordLrns = async (lrns: string[]): Promise => { const registry = getRegistry(); - const result = await registry.resolveNames([PRICING_RECORD_LRN]); - const pricingRecordAttributes: PricingRecordAttributes = result[0].attributes; + const result = await registry.resolveNames(lrns); + const pricingRecordsAttributes: PricingRecordAttributes[] = result.map((record: any) => { + return record.attributes + }); - if (pricingRecordAttributes.for !== VALID_PRICING_RECORD_FOR) { - throw new Error(`Incorrect pricing record type: ${pricingRecordAttributes.type}. Please provide correct pricing record lrn`) + return pricingRecordsAttributes; +}; + +export const getCostOfDeployment = async (): Promise => { + 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.find(record => record.for === ALNT); + // Find the deployment cost record (ALNT cost for webapp-deployment) + const deploymentCostRecord = resolvedRecords.find(record => record.for === DEPLOYMENT); + + if (!alntPriceRecord || !deploymentCostRecord) { + throw new Error('Required pricing records not found'); } - if (pricingRecordAttributes.currency !== SUPPORTED_CURRENCY) { - throw new Error(`Unsupported currency found in pricing record: ${pricingRecordAttributes.currency}`) - } + // Convert strings to numbers for calculation + const alntPriceUsd = parseFloat(alntPriceRecord.amount); // USD per ALNT + const deploymentCostAlnt = parseFloat(deploymentCostRecord.amount); // ALNT required - return pricingRecordAttributes; + // Calculate deployment cost in USD: (ALNT required) * (USD per ALNT) + const deploymentCostUsd = deploymentCostAlnt * alntPriceUsd; + + // Return with 6 decimal precision + return parseFloat(deploymentCostUsd.toFixed(6)); } -- 2.45.2 From 6690fa3899b8d9c0aa706aa262d5b1b91e558a56 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 24 Jul 2025 19:06:32 +0530 Subject: [PATCH 10/19] Update steps to publish records --- deploy/publish-pricing.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/deploy/publish-pricing.md b/deploy/publish-pricing.md index 44eb3c1..7133299 100644 --- a/deploy/publish-pricing.md +++ b/deploy/publish-pricing.md @@ -16,7 +16,7 @@ nano config.yml ``` -## Create Bond +## Create Bond (optional) - Create bond: @@ -30,7 +30,11 @@ npm run laconic -- bond get --id ``` -## Publish Record for Cost of alnt +## Publish Record + +NOTE: Publishing record requires a bond with enough funds, if you don't have a bond check [steps to create bond](#create-bond-optional) + +### Publish Record for Cost of alnt - Update `for`, `cost` and `currency` fields in [pricing.yml](./pricing.yml) file: @@ -42,10 +46,14 @@ ... ``` + - Amount calculation: + - Cost of 1 deployment is `12960` in terms of `alnt` or `5` in terms of `USD` + - So cost of 1 `alnt` comes out be `0.000385802 USD` rounded off to 6 decimals + - Publish the record: ```bash - npm run laconic -- record publish --filename deploy/pricing.yml --bond-id --gas 250000 --fees 250000alnt + npm run laconic -- record publish --filename deploy/pricing.yml --bond-id ``` - Get record info: @@ -54,7 +62,7 @@ npm run laconic -- record get --id ``` -## Publish Record for Cost of Deployment +### Publish Record for Cost of Deployment - Update `for`, `cost` and `currency` fields in [pricing.yml](./pricing.yml) file: @@ -69,7 +77,7 @@ - Publish the record: ```bash - npm run laconic -- record publish --filename deploy/pricing.yml --bond-id --gas 250000 --fees 250000alnt + npm run laconic -- record publish --filename deploy/pricing.yml --bond-id ``` - Get record info: -- 2.45.2 From 8f8a561aa9f48f84e22fcf8d4ff5a81d33db0d9c Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 11:29:21 +0530 Subject: [PATCH 11/19] Add script to run commands for publishing records from container --- .env.example | 5 +- deploy/README.md | 29 +++--- deploy/laconic-cli.sh | 50 ++++++++++ deploy/publish-pricing.md | 168 ++++++++++++++++++-------------- src/app/api/registry/route.ts | 6 -- src/components/PaymentModal.tsx | 3 - src/config/index.ts | 12 +-- src/services/registry.ts | 4 +- src/types/index.ts | 3 - 9 files changed, 167 insertions(+), 113 deletions(-) create mode 100755 deploy/laconic-cli.sh diff --git a/.env.example b/.env.example index df7daba..fb64ae2 100644 --- a/.env.example +++ b/.env.example @@ -20,9 +20,8 @@ NEXT_PUBLIC_EXAMPLE_URL=https://git.vdb.to/cerc-io/test-progressive-web-app 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_REGISTRY_GAS_PRICE=0.001 -NEXT_PUBLIC_ALNT_COST_LRN= -NEXT_PUBLIC_DEPLOYMENT_COST_LRN= +NEXT_PUBLIC_ALNT_COST_LRN=lrn://laconic/pricing/alnt +NEXT_PUBLIC_DEPLOYMENT_COST_LRN=lrn://laconic/pricing/webapp-deployment REGISTRY_BOND_ID= REGISTRY_AUTHORITY= REGISTRY_USER_KEY= diff --git a/deploy/README.md b/deploy/README.md index be5ed5f..71a087f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,17 +1,26 @@ # Deploy +## Prerequisites + +This project requires pricing records for cost of deployment and cost of alnt to be published + +- Cost of deployment: `lrn://laconic/pricing/webapp-deployment` +- Cost of alnt: `lrn://laconic/pricing/alnt` + +If these records are not available, [follow these steps to publish them](./publish-pricing.md) + ## Setup ### 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 +28,13 @@ # 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): ```bash nano config.yml ``` -* Add configuration for registry operations: +- Add configuration for registry operations: ```bash cp .registry.env.example .registry.env @@ -34,7 +43,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 @@ -45,9 +54,7 @@ ## Run -### gor-deploy - -* Deploy `gor-deploy` App: +- Deploy `gor-deploy` App: ```bash # In gor-deploy/deploy dir @@ -58,13 +65,13 @@ ./deploy.sh ``` -* Check deployment logs on deployer UI: +- Check deployment logs on deployer UI: -* Visit deployed app: +- Visit deployed app: ### Remove deployment -* Remove deployment: +- Remove deployment: ```bash # In gor-deploy/deploy dir diff --git a/deploy/laconic-cli.sh b/deploy/laconic-cli.sh new file mode 100755 index 0000000..2325582 --- /dev/null +++ b/deploy/laconic-cli.sh @@ -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 \ + "$@" diff --git a/deploy/publish-pricing.md b/deploy/publish-pricing.md index 7133299..79b077a 100644 --- a/deploy/publish-pricing.md +++ b/deploy/publish-pricing.md @@ -1,35 +1,36 @@ # publish-pricing -## Prerequisites - -- Install packages: - - ```bash - npm install - ``` - ## 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 + ``` + +- Make the CLI script executable: + + ```bash + chmod +x laconic-cli.sh + ``` + - Configure `userKey` in the [registry CLI config](./config.yml): + NOTE: User key should be of the account that owns the `laconic` authority + ```bash nano config.yml ``` -## Create Bond (optional) - -- Create bond: - - ```bash - npm run laconic -- bond create --type alnt --quantity 100000000 - ``` - -- Get bond info: - - ```bash - npm run laconic -- bond get --id - ``` - ## Publish Record NOTE: Publishing record requires a bond with enough funds, if you don't have a bond check [steps to create bond](#create-bond-optional) @@ -48,18 +49,18 @@ NOTE: Publishing record requires a bond with enough funds, if you don't have a b - Amount calculation: - Cost of 1 deployment is `12960` in terms of `alnt` or `5` in terms of `USD` - - So cost of 1 `alnt` comes out be `0.000385802 USD` rounded off to 6 decimals + - Hence, cost of 1 `alnt` comes out be `0.000385802 USD` rounded off to 6 decimals - Publish the record: ```bash - npm run laconic -- record publish --filename deploy/pricing.yml --bond-id + ./laconic-cli.sh record publish --filename pricing.yml --bond-id ``` - Get record info: ```bash - npm run laconic -- record get --id + ./laconic-cli.sh record get --id ``` ### Publish Record for Cost of Deployment @@ -77,73 +78,29 @@ NOTE: Publishing record requires a bond with enough funds, if you don't have a b - Publish the record: ```bash - npm run laconic -- record publish --filename deploy/pricing.yml --bond-id + ./laconic-cli.sh record publish --filename pricing.yml --bond-id ``` - Get record info: ```bash - npm run laconic -- record get --id - ``` - -## Reserve a New Authority (optional) - -- Reserve authority: - - ```bash - npm run laconic -- authority reserve laconic - ``` - -- Check authority info: - - ```bash - npm run laconic -- authority whois laconic - ``` - - - Note down auction ID from authority info as it is required in next steps - -- Get auction info: - - ```bash - npm run laconic -- auction get - ``` - -- Commit an auction bid: - - ```bash - npm run laconic -- auction bid commit 25000000 alnt - - Reveal file: ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json - ``` - -- Reveal bid: - - ```bash - npm run laconic -- auction bid reveal ./out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json - ``` - -### Set Authority Bond - -- Set authority bond after winning auction: - - ```bash - npm run laconic -- authority bond set laconic + ./laconic-cli.sh record get --id ``` ## Set Record Name -NOTE: To set record name an authority with an authority bond is required +NOTE: To set record name an authority with an authority bond is required, if you don't have an authority check [steps to reserve a new authority](#reserve-a-new-authority-optional) - Set record name for cost of alnt record ```bash - npm run laconic -- name set lrn:///pricing/alnt + ./laconic-cli.sh name set lrn://laconic/pricing/alnt ``` - Set record name for cost of deployment record ```bash - npm run laconic -- name set lrn:///pricing/webapp-deployment + ./laconic-cli.sh name set lrn://laconic/pricing/webapp-deployment ``` ## Delete Record Name @@ -151,5 +108,66 @@ NOTE: To set record name an authority with an authority bond is required - Delete record name: ```bash - npm run laconic -- name delete + ./laconic-cli.sh name delete + ``` + +## Create Bond (optional) + +- Create bond: + + ```bash + ./laconic-cli.sh bond create --type alnt --quantity 100000000 + ``` + +- Get bond info: + + ```bash + ./laconic-cli.sh bond get --id + ``` + +## Reserve a New Authority (optional) + +Below steps are used to reserve `laconic` authority + +- Reserve authority: + + ```bash + ./laconic-cli.sh authority reserve laconic + ``` + +- 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 + ``` + +- Commit an auction bid: + + ```bash + ./laconic-cli.sh auction bid commit 25000000 alnt + + # Path inside container + Reveal file: /app/deploy/out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + ``` + +- Reveal bid: + + ```bash + ./laconic-cli.sh auction bid reveal /app/deploy/out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + ``` + +### Set Authority Bond + +- Set authority bond after winning auction: + + ```bash + ./laconic-cli.sh authority bond set laconic ``` diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index 7ec48f0..78f1388 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -3,9 +3,7 @@ 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'; @@ -351,10 +349,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 diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index be9e330..2e6f212 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -17,9 +17,6 @@ assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL const GORBAGANA_RPC_URL = process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL; -assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); -assert(process.env.NEXT_PUBLIC_PRICING_RECORD_LRN, 'DEPLOYMENT_RECORD_LRN is required'); - export default function PaymentModal({ isOpen, onClose, diff --git a/src/config/index.ts b/src/config/index.ts index 0a9954b..bbd2591 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,5 +1,4 @@ -import { Registry, DENOM as ALNT_DENOM } from '@cerc-io/registry-sdk'; -import { GasPrice } from '@cosmjs/stargate'; +import { Registry } from '@cerc-io/registry-sdk'; import { RegistryConfig } from '../types'; @@ -8,12 +7,11 @@ let registryInstance: Registry | null = null; export const getRegistry = (): Registry => { if (!registryInstance) { const config = getClientRegistryConfig(); - const gasPrice = GasPrice.fromString(config.fee.gasPrice + ALNT_DENOM); registryInstance = new Registry( config.gqlEndpoint, config.rpcEndpoint, - { chainId: config.chainId, gasPrice } + { chainId: config.chainId } ); } return registryInstance; @@ -24,9 +22,6 @@ export const getClientRegistryConfig = () => { chainId: process.env.NEXT_PUBLIC_REGISTRY_CHAIN_ID!, rpcEndpoint: process.env.NEXT_PUBLIC_REGISTRY_RPC_ENDPOINT!, gqlEndpoint: process.env.NEXT_PUBLIC_REGISTRY_GQL_ENDPOINT!, - fee: { - gasPrice: process.env.NEXT_PUBLIC_REGISTRY_GAS_PRICE!, - }, }; }; @@ -54,8 +49,5 @@ export const getRegistryConfig = (): RegistryConfig => { 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', - }, }; }; diff --git a/src/services/registry.ts b/src/services/registry.ts index 4962d89..8a9c226 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -3,8 +3,8 @@ import assert from 'assert'; import { getRegistry } from '@/config'; import { CreateRecordResponse, PricingRecordAttributes, PaymentMethod } from '../types'; -assert(process.env.NEXT_PUBLIC_DEPLOYMENT_COST_LRN, 'DEPLOYMENT_RECORD_LRN is required'); -assert(process.env.NEXT_PUBLIC_ALNT_COST_LRN, 'DEPLOYMENT_RECORD_LRN is required'); +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 DEPLOYMENT = 'webapp-deployment'; diff --git a/src/types/index.ts b/src/types/index.ts index 9dab16e..16258a6 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -10,9 +10,6 @@ export interface RegistryConfig { bondId: string; authority: string; privateKey: string; - fee: { - gasPrice: string; - }; } export interface CreateRecordResponse { -- 2.45.2 From 6b076766842c10bc17d27d769483a64c0e636d4f Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 12:15:58 +0530 Subject: [PATCH 12/19] Add gorbagana chain genesis hash reference --- src/app/api/registry/route.ts | 3 ++- src/app/page.tsx | 10 +++++++++- src/components/PaymentModal.tsx | 3 ++- src/constants/payments.ts | 2 -- src/utils/gorbagana.ts | 1 + 5 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 src/utils/gorbagana.ts diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index 78f1388..4d0c429 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -9,9 +9,10 @@ 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'); diff --git a/src/app/page.tsx b/src/app/page.tsx index 0aa153e..bd80876 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -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() { diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index 2e6f212..03012d8 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -9,9 +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'); diff --git a/src/constants/payments.ts b/src/constants/payments.ts index 4b67298..7e0c683 100644 --- a/src/constants/payments.ts +++ b/src/constants/payments.ts @@ -7,5 +7,3 @@ export const PAYMENT_METHOD_LABELS: Record = { }; export const SOLANA_GOR_MINT_ADDRESS = '71Jvq4Epe2FCJ7JFSF7jLXdNk1Wy4Bhqd9iL6bEFELvg'; - -export const IS_NAT_GOR_TRANSFER_ENABLED = process.env.NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER === "true"; diff --git a/src/utils/gorbagana.ts b/src/utils/gorbagana.ts new file mode 100644 index 0000000..8555e72 --- /dev/null +++ b/src/utils/gorbagana.ts @@ -0,0 +1 @@ +export const IS_NAT_GOR_TRANSFER_ENABLED = process.env.NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER === "true"; -- 2.45.2 From aae48cdef4b4aae87efff313e2d8532ac631fe0d Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 13:32:00 +0530 Subject: [PATCH 13/19] Create separate record files --- .gitignore | 3 ++ deploy/alnt-pricing.yml | 6 ++++ deploy/pricing.yml | 6 ---- deploy/publish-pricing.md | 46 +++++++++------------------- deploy/webapp-deployment-pricing.yml | 6 ++++ src/services/registry.ts | 8 ++--- 6 files changed, 32 insertions(+), 43 deletions(-) create mode 100644 deploy/alnt-pricing.yml delete mode 100644 deploy/pricing.yml create mode 100644 deploy/webapp-deployment-pricing.yml diff --git a/.gitignore b/.gitignore index 1ec5286..e6d23e2 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ yarn-error.log* # typescript *.tsbuildinfo + +# Reveal file out dir +out \ No newline at end of file diff --git a/deploy/alnt-pricing.yml b/deploy/alnt-pricing.yml new file mode 100644 index 0000000..e3529e1 --- /dev/null +++ b/deploy/alnt-pricing.yml @@ -0,0 +1,6 @@ +record: + type: PricingRecord + for: "alnt" + amount: "0.000386" + currency: "USD" + version: 1.0.0 diff --git a/deploy/pricing.yml b/deploy/pricing.yml deleted file mode 100644 index 8fe991e..0000000 --- a/deploy/pricing.yml +++ /dev/null @@ -1,6 +0,0 @@ -record: - type: PricingRecord - for: "" - amount: "" - currency: "" - version: 1.0.0 diff --git a/deploy/publish-pricing.md b/deploy/publish-pricing.md index 79b077a..680ddb9 100644 --- a/deploy/publish-pricing.md +++ b/deploy/publish-pricing.md @@ -17,12 +17,6 @@ # Builds image cerc/laconic-registry-cli:latest ``` -- Make the CLI script executable: - - ```bash - chmod +x laconic-cli.sh - ``` - - Configure `userKey` in the [registry CLI config](./config.yml): NOTE: User key should be of the account that owns the `laconic` authority @@ -37,24 +31,14 @@ NOTE: Publishing record requires a bond with enough funds, if you don't have a b ### Publish Record for Cost of alnt -- Update `for`, `cost` and `currency` fields in [pricing.yml](./pricing.yml) file: - - ```bash - ... - for: "alnt" - amount: "0.000385802" - currency: "USD" - ... - ``` - - - Amount calculation: - - 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.000385802 USD` rounded off to 6 decimals +- alnt price calculation (reference: ): + - 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 pricing.yml --bond-id + ./laconic-cli.sh record publish --filename alnt-pricing.yml --bond-id ``` - Get record info: @@ -65,20 +49,10 @@ NOTE: Publishing record requires a bond with enough funds, if you don't have a b ### Publish Record for Cost of Deployment -- Update `for`, `cost` and `currency` fields in [pricing.yml](./pricing.yml) file: - - ```bash - ... - for: "webapp-deployment" - amount: "12960" - currency: "alnt" - ... - ``` - - Publish the record: ```bash - ./laconic-cli.sh record publish --filename pricing.yml --bond-id + ./laconic-cli.sh record publish --filename webapp-deployment-pricing.yml --bond-id ``` - Get record info: @@ -89,7 +63,9 @@ NOTE: Publishing record requires a bond with enough funds, if you don't have a b ## Set Record Name -NOTE: To set record name an authority with an authority bond is required, if you don't have an authority check [steps to reserve a new authority](#reserve-a-new-authority-optional) +NOTE: To set record name an authority is required, if you don't have an authority check [steps to reserve a new authority](#reserve-a-new-authority-optional) + +These record names should be under `laconic` authority - Set record name for cost of alnt record @@ -158,12 +134,18 @@ Below steps are used to reserve `laconic` authority Reveal file: /app/deploy/out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json ``` + - The commit phase lasts for 1 minute after reserving the authority so please commit the auction bid within this time period + - Reveal bid: ```bash ./laconic-cli.sh auction bid reveal /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 + +- To use this published authority for setting record names, authority bond is also required + ### Set Authority Bond - Set authority bond after winning auction: diff --git a/deploy/webapp-deployment-pricing.yml b/deploy/webapp-deployment-pricing.yml new file mode 100644 index 0000000..abfc3a6 --- /dev/null +++ b/deploy/webapp-deployment-pricing.yml @@ -0,0 +1,6 @@ +record: + type: PricingRecord + for: "webapp-deployment" + amount: "12960" + currency: "alnt" + version: 1.0.0 diff --git a/src/services/registry.ts b/src/services/registry.ts index 8a9c226..cf0206b 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -7,9 +7,7 @@ assert(process.env.NEXT_PUBLIC_DEPLOYMENT_COST_LRN, 'DEPLOYMENT_COST_LRN is requ 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 DEPLOYMENT = 'webapp-deployment'; const ALNT_COST_LRN = process.env.NEXT_PUBLIC_ALNT_COST_LRN; -const ALNT = 'alnt'; export const createApplicationDeploymentRequest = async ( url: string, @@ -76,9 +74,9 @@ export const getCostOfDeployment = async (): Promise => { console.log('resolvedRecords:', resolvedRecords); // Find the ALNT price record (USD per ALNT) - const alntPriceRecord = resolvedRecords.find(record => record.for === ALNT); + const alntPriceRecord = resolvedRecords[0]; // Find the deployment cost record (ALNT cost for webapp-deployment) - const deploymentCostRecord = resolvedRecords.find(record => record.for === DEPLOYMENT); + const deploymentCostRecord = resolvedRecords[1]; if (!alntPriceRecord || !deploymentCostRecord) { throw new Error('Required pricing records not found'); @@ -92,5 +90,5 @@ export const getCostOfDeployment = async (): Promise => { const deploymentCostUsd = deploymentCostAlnt * alntPriceUsd; // Return with 6 decimal precision - return parseFloat(deploymentCostUsd.toFixed(6)); + return parseFloat(deploymentCostUsd.toFixed(2)); } -- 2.45.2 From eeed871583b9922b9e769bdecf5396126356e8f7 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 13:51:54 +0530 Subject: [PATCH 14/19] Fix null token amount checking --- src/components/PaymentModal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index 03012d8..3d6b265 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -50,7 +50,7 @@ export default function PaymentModal({ // Fetch payment amount based on USD price for both payment methods useEffect(() => { - if (!isOpen || !deploymentCost || !paymentMethod) return; + if (!isOpen || deploymentCost === null || !paymentMethod) return; const fetchPaymentAmount = async () => { setLoadingPrice(true); @@ -86,7 +86,7 @@ export default function PaymentModal({ useEffect(() => { if (isOpen) { setError(''); - setTokenAmount(0); + setTokenAmount(-1); } }, [isOpen]); @@ -95,7 +95,7 @@ export default function PaymentModal({ return; } - if (tokenAmount === 0 || loadingPrice) { + if (tokenAmount === -1 || loadingPrice) { setError('Payment amount not ready. Please wait.'); return; } -- 2.45.2 From 083feb4e558186fc95f7fbc124fbf6e5ea3447b9 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 14:14:07 +0530 Subject: [PATCH 15/19] Round off USD value while displaying --- src/components/PaymentModal.tsx | 8 ++++---- src/services/registry.ts | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index 3d6b265..496f06c 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -50,7 +50,7 @@ export default function PaymentModal({ // Fetch payment amount based on USD price for both payment methods useEffect(() => { - if (!isOpen || deploymentCost === null || !paymentMethod) return; + if (!isOpen || !deploymentCost || !paymentMethod) return; const fetchPaymentAmount = async () => { setLoadingPrice(true); @@ -86,7 +86,7 @@ export default function PaymentModal({ useEffect(() => { if (isOpen) { setError(''); - setTokenAmount(-1); + setTokenAmount(0); } }, [isOpen]); @@ -95,7 +95,7 @@ export default function PaymentModal({ return; } - if (tokenAmount === -1 || loadingPrice) { + if (tokenAmount === 0 || loadingPrice) { setError('Payment amount not ready. Please wait.'); return; } @@ -192,7 +192,7 @@ export default function PaymentModal({
=> { const deploymentCostAlnt = parseFloat(deploymentCostRecord.amount); // ALNT required // Calculate deployment cost in USD: (ALNT required) * (USD per ALNT) - const deploymentCostUsd = deploymentCostAlnt * alntPriceUsd; - - // Return with 6 decimal precision - return parseFloat(deploymentCostUsd.toFixed(2)); + return deploymentCostAlnt * alntPriceUsd; } -- 2.45.2 From a6f884e3c85038a8149809853321bf98f153eaa2 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 17:06:10 +0530 Subject: [PATCH 16/19] Update readme for publishing records --- .env.example | 2 +- README.md | 23 ++++++++-------- deploy/README.md | 29 ++++++++++++++------ deploy/publish-pricing.md | 58 +++++++++++++++++---------------------- 4 files changed, 58 insertions(+), 54 deletions(-) diff --git a/.env.example b/.env.example index fb64ae2..5549fb6 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ # 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 diff --git a/README.md b/README.md index 67f91f7..35d83bb 100644 --- a/README.md +++ b/README.md @@ -22,32 +22,33 @@ A simple Next.js frontend that allows users to pay in GOR tokens (configurable S ## Environment Variables -Copy the `.env.local.example` file to `.env.local` and fill in the required variables: +Copy the `.env.example` file to `.env.local` and fill in the required variables: ```bash -cp .env.local.example .env.local +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 +- `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_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_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") -- `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 ## Installation diff --git a/deploy/README.md b/deploy/README.md index 71a087f..97735fd 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,14 +1,5 @@ # Deploy -## Prerequisites - -This project requires pricing records for cost of deployment and cost of alnt to be published - -- Cost of deployment: `lrn://laconic/pricing/webapp-deployment` -- Cost of alnt: `lrn://laconic/pricing/alnt` - -If these records are not available, [follow these steps to publish them](./publish-pricing.md) - ## Setup ### gor-deploy @@ -30,10 +21,29 @@ If these records are not available, [follow these steps to publish them](./publi - Configure `userKey` and `bondId` in the [registry CLI config](./config.yml): + NOTE: The bond id should be set as authority bond of `laconic-deploy` and user key should be of the account that owns the `laconic-deploy` authority (owner account address: `laconic1kwx2jm6vscz38qlyujvq6msujmk8l3zangqahs`) + ```bash nano config.yml ``` +- This project requires pricing records for cost of deployment and cost of alnt to be published + + - Cost of deployment: `lrn://laconic/pricing/webapp-deployment` + - Cost of alnt: `lrn://laconic/pricing/alnt` + + If these records are not available, [follow these steps to publish them](./publish-pricing.md) + + - 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 + ``` + - Add configuration for registry operations: ```bash @@ -51,6 +61,7 @@ If these records are not available, [follow these steps to publish them](./publi # Fill in the required values nano .app.env ``` + ## Run diff --git a/deploy/publish-pricing.md b/deploy/publish-pricing.md index 680ddb9..d246425 100644 --- a/deploy/publish-pricing.md +++ b/deploy/publish-pricing.md @@ -19,15 +19,19 @@ - Configure `userKey` in the [registry CLI config](./config.yml): - NOTE: User key should be of the account that owns the `laconic` authority + NOTE: 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 +## Publish Record and Set Record Name -NOTE: Publishing record requires a bond with enough funds, if you don't have a bond check [steps to create bond](#create-bond-optional) +Publishing record requires a bond with enough funds (min. 10000000alnt ), if you don't have a bond check [steps to create bond](#create-bond-optional) + +To set record name an authority is required, if you don't have an authority check [steps to reserve a new authority](#reserve-a-new-authority-optional) + +Make sure, the record names are under `laconic` authority ### Publish Record for Cost of alnt @@ -47,6 +51,14 @@ NOTE: Publishing record requires a bond with enough funds, if you don't have a b ./laconic-cli.sh record get --id ``` +### Set Record Name + +- Set record name for cost of alnt record + + ```bash + ./laconic-cli.sh name set lrn://laconic/pricing/alnt + ``` + ### Publish Record for Cost of Deployment - Publish the record: @@ -61,17 +73,7 @@ NOTE: Publishing record requires a bond with enough funds, if you don't have a b ./laconic-cli.sh record get --id ``` -## Set Record Name - -NOTE: To set record name an authority is required, if you don't have an authority check [steps to reserve a new authority](#reserve-a-new-authority-optional) - -These record names should be under `laconic` authority - -- Set record name for cost of alnt record - - ```bash - ./laconic-cli.sh name set lrn://laconic/pricing/alnt - ``` +### Set Record Name - Set record name for cost of deployment record @@ -79,20 +81,14 @@ These record names should be under `laconic` authority ./laconic-cli.sh name set lrn://laconic/pricing/webapp-deployment ``` -## Delete Record Name - -- Delete record name: - - ```bash - ./laconic-cli.sh name delete - ``` +- Now you should be able to use these records in the app ## Create Bond (optional) - Create bond: ```bash - ./laconic-cli.sh bond create --type alnt --quantity 100000000 + ./laconic-cli.sh bond create --type alnt --quantity 10000000 ``` - Get bond info: @@ -111,6 +107,8 @@ Below steps are used to reserve `laconic` authority ./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 @@ -128,27 +126,21 @@ Below steps are used to reserve `laconic` authority - Commit an auction bid: ```bash - ./laconic-cli.sh auction bid commit 25000000 alnt + ./laconic-cli.sh auction bid commit 5000000 alnt - # Path inside container + # Example file path inside container Reveal file: /app/deploy/out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json ``` - - The commit phase lasts for 1 minute after reserving the authority so please commit the auction bid within this time period +- 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 /app/deploy/out/bafyreiay2rccax64yn4ljhvzvm3jkbebvzheyucuma5jlbpzpzd5i5gjuy.json + ./laconic-cli.sh auction bid reveal /app/deploy/out/.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 - -- To use this published authority for setting record names, authority bond is also required - -### Set Authority Bond - -- Set authority bond after winning auction: +- Set authority bond after winning auction as it is required to use the published authority: ```bash ./laconic-cli.sh authority bond set laconic -- 2.45.2 From 39f2d7c4ebec82301c465d1806239ba098086054 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 17:17:16 +0530 Subject: [PATCH 17/19] Document relevant environment variables --- README.md | 63 +++++++++--------------------------------------- deploy/README.md | 18 +++++++++++++- 2 files changed, 28 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 35d83bb..135e5b8 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,17 @@ 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 + +Follow [these steps](./deploy/README.md) to deploy this app to production + +## Installation + +```bash +npm install +``` + +## Development Copy the `.env.example` file to `.env.local` and fill in the required variables: @@ -51,14 +61,6 @@ Server-side: - `REGISTRY_USER_KEY` - The private key for Laconic Registry transactions (also used for LNT transfers) - `DEPLOYER_LRN` - The LRN of the deployer -## Installation - -```bash -npm install -``` - -## Development - ```bash npm run dev ``` @@ -131,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. @@ -182,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. diff --git a/deploy/README.md b/deploy/README.md index 97735fd..6b8f8e5 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -61,7 +61,23 @@ # Fill in the required values 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 -- 2.45.2 From 68080b61b3859c9cd77c0c19a5174c0cb54c1f73 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 18:04:45 +0530 Subject: [PATCH 18/19] Add more prose to readme for publishing records --- deploy/README.md | 11 +++++----- deploy/publish-pricing.md | 20 +++++++++---------- deploy/{ => records}/alnt-pricing.yml | 0 .../webapp-deployment-pricing.yml | 0 4 files changed, 15 insertions(+), 16 deletions(-) rename deploy/{ => records}/alnt-pricing.yml (100%) rename deploy/{ => records}/webapp-deployment-pricing.yml (100%) diff --git a/deploy/README.md b/deploy/README.md index 6b8f8e5..5ac2ef3 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -21,7 +21,9 @@ - Configure `userKey` and `bondId` in the [registry CLI config](./config.yml): - NOTE: The bond id should be set as authority bond of `laconic-deploy` and user key should be of the account that owns the `laconic-deploy` authority (owner account address: `laconic1kwx2jm6vscz38qlyujvq6msujmk8l3zangqahs`) + - 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 @@ -29,11 +31,6 @@ - This project requires pricing records for cost of deployment and cost of alnt to be published - - Cost of deployment: `lrn://laconic/pricing/webapp-deployment` - - Cost of alnt: `lrn://laconic/pricing/alnt` - - If these records are not available, [follow these steps to publish them](./publish-pricing.md) - - Check if these records are available by running following commands: ```bash @@ -44,6 +41,8 @@ ./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 diff --git a/deploy/publish-pricing.md b/deploy/publish-pricing.md index d246425..c943dae 100644 --- a/deploy/publish-pricing.md +++ b/deploy/publish-pricing.md @@ -19,7 +19,7 @@ - Configure `userKey` in the [registry CLI config](./config.yml): - NOTE: 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) + 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 @@ -27,9 +27,9 @@ ## Publish Record and Set Record Name -Publishing record requires a bond with enough funds (min. 10000000alnt ), if you don't have a bond check [steps to create bond](#create-bond-optional) +Publishing record requires a bond with enough funds as rent is taken for each record from the bond every year -To set record name an authority is required, if you don't have an authority check [steps to reserve a new authority](#reserve-a-new-authority-optional) +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 @@ -42,7 +42,7 @@ Make sure, the record names are under `laconic` authority - Publish the record: ```bash - ./laconic-cli.sh record publish --filename alnt-pricing.yml --bond-id + ./laconic-cli.sh record publish --filename records/alnt-pricing.yml --bond-id ``` - Get record info: @@ -51,9 +51,7 @@ Make sure, the record names are under `laconic` authority ./laconic-cli.sh record get --id ``` -### Set Record Name - -- Set record name for cost of alnt record +- Set record name for cost of alnt record: ```bash ./laconic-cli.sh name set lrn://laconic/pricing/alnt @@ -64,7 +62,7 @@ Make sure, the record names are under `laconic` authority - Publish the record: ```bash - ./laconic-cli.sh record publish --filename webapp-deployment-pricing.yml --bond-id + ./laconic-cli.sh record publish --filename records/webapp-deployment-pricing.yml --bond-id ``` - Get record info: @@ -73,8 +71,6 @@ Make sure, the record names are under `laconic` authority ./laconic-cli.sh record get --id ``` -### Set Record Name - - Set record name for cost of deployment record ```bash @@ -83,6 +79,8 @@ Make sure, the record names are under `laconic` authority - 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: @@ -126,6 +124,8 @@ Below steps are used to reserve `laconic` authority - Commit an auction bid: ```bash + # 5000000 alnt is the minimum bid amount for authority auction + ./laconic-cli.sh auction bid commit 5000000 alnt # Example file path inside container diff --git a/deploy/alnt-pricing.yml b/deploy/records/alnt-pricing.yml similarity index 100% rename from deploy/alnt-pricing.yml rename to deploy/records/alnt-pricing.yml diff --git a/deploy/webapp-deployment-pricing.yml b/deploy/records/webapp-deployment-pricing.yml similarity index 100% rename from deploy/webapp-deployment-pricing.yml rename to deploy/records/webapp-deployment-pricing.yml -- 2.45.2 From b6f4b4067f2c1c68b35c1a2f0ce692907a81747e Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Fri, 25 Jul 2025 19:02:50 +0530 Subject: [PATCH 19/19] Add registry gas price config --- .env.example | 1 + src/components/PaymentModal.tsx | 37 ++++++++++++++++++++++----------- src/config/index.ts | 11 ++++++++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/.env.example b/.env.example index 5549fb6..6f7943c 100644 --- a/.env.example +++ b/.env.example @@ -22,6 +22,7 @@ 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= REGISTRY_USER_KEY= diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index 496f06c..654c193 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -190,19 +190,32 @@ export default function PaymentModal({
- + color: 'var(--muted)' + }}> + + + + +
+ ) : ( + + )}
USD
diff --git a/src/config/index.ts b/src/config/index.ts index bbd2591..473f4fd 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,17 +1,24 @@ -import { Registry } from '@cerc-io/registry-sdk'; +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 = 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 } + { + chainId: config.chainId, + gasPrice, + } ); } return registryInstance; -- 2.45.2