diff --git a/.github/workflows/test_backend.yml b/.github/workflows/test_backend.yml index aa651f28c..15433a89f 100644 --- a/.github/workflows/test_backend.yml +++ b/.github/workflows/test_backend.yml @@ -31,6 +31,9 @@ on: workflow_run: workflows: ["Build and deploy GovTool test stack"] types: [completed] + branches: + - test + - infra/test-chores concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/test_integration_playwright.yml b/.github/workflows/test_integration_playwright.yml index ea6406cfe..4a186dbca 100644 --- a/.github/workflows/test_integration_playwright.yml +++ b/.github/workflows/test_integration_playwright.yml @@ -16,6 +16,7 @@ on: - "sanchogov.tools" - "staging.govtool.byron.network" - "govtool.cardanoapi.io" + - "p80-z6b8d2f7a-ze34e4cb2-gtw.z937eb260.rustrocks.fr" - "preview.gov.tools" - "gov.tools" - "p80-z78acf3c2-zded6a792-gtw.z937eb260.rustrocks.fr" @@ -32,6 +33,9 @@ on: workflow_run: workflows: ["Build and deploy GovTool test stack"] types: [completed] + branches: + - test + - infra/test-chores concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -90,20 +94,16 @@ jobs: # Set API keys based on the network if [[ "${{ env.NETWORK }}" == "preprod" ]]; then - export FAUCET_API_KEY="${{ secrets.FAUCET_API_KEY_PREPROD }}" export BLOCKFROST_API_KEY="${{ secrets.BLOCKFROST_API_KEY_PREPROD }}" elif [[ "${{ env.NETWORK }}" == "sanchonet" ]]; then - export FAUCET_API_KEY="${{ secrets.FAUCET_API_KEY_SANCHONET }}" export BLOCKFROST_API_KEY="${{ secrets.BLOCKFROST_API_KEY_SANCHONET }}" elif [[ "${{ env.NETWORK }}" == "preview" ]]; then - export FAUCET_API_KEY="${{ secrets.FAUCET_API_KEY_PREVIEW }}" export BLOCKFROST_API_KEY="${{ secrets.BLOCKFROST_API_KEY_PREVIEW }}" else - export FAUCET_API_KEY="${{ secrets.FAUCET_API_KEY_PREVIEW }}" export BLOCKFROST_API_KEY="${{ secrets.BLOCKFROST_API_KEY_MAINNET }}" fi - npm test + npm run test:headless - name: Upload report uses: actions/upload-artifact@v4 @@ -120,7 +120,6 @@ jobs: path: tests/govtool-frontend/playwright/lock_logs.txt env: - API_URL: https://${{inputs.deployment || 'govtool.cardanoapi.io' }}/api DOCS_URL: ${{ vars.DOCS_URL }} KUBER_API_KEY: ${{secrets.KUBER_API_KEY}} NETWORK: ${{ inputs.network || vars.NETWORK }} @@ -128,9 +127,8 @@ jobs: CI: ${{vars.CI}} FAUCET_ADDRESS: ${{vars.FAUCET_ADDRESS}} CARDANOAPI_METADATA_URL: ${{vars.CARDANOAPI_METADATA_URL}} - PROPOSAL_FAUCET_PAYMENT_PRIVATE: ${{secrets.PROPOSAL_FAUCET_PAYMENT_PRIVATE}} - PROPOSAL_FAUCET_STAKE_PRIVATE: ${{secrets.PROPOSAL_FAUCET_STAKE_PRIVATE}} - PROPOSAL_FAUCET_DREP_PRIVATE: ${{secrets.PROPOSAL_FAUCET_DREP_PRIVATE}} + FAUCET_PAYMENT_PRIVATE: ${{secrets.FAUCET_PAYMENT_PRIVATE}} + FAUCET_STAKE_PKH: ${{secrets.FAUCET_STAKE_PKH}} publish-report: runs-on: ubuntu-latest diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 2f7e1e056..435748478 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -13,9 +13,9 @@ "@emotion/styled": "^11.11.0", "@emurgo/cardano-serialization-lib-asmjs": "^14.1.1", "@hookform/resolvers": "^3.3.1", - "@intersect.mbo/govtool-outcomes-pillar-ui": "1.4.0", + "@intersect.mbo/govtool-outcomes-pillar-ui": "1.4.1", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.7.0-beta-24", + "@intersect.mbo/pdf-ui": "0.7.0-beta-25", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@rollup/plugin-babel": "^6.0.4", @@ -3390,9 +3390,9 @@ } }, "node_modules/@intersect.mbo/govtool-outcomes-pillar-ui": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.4.0.tgz", - "integrity": "sha512-iSg6FzeUW4F3KSQDcHCytggCG68Q4OKUzQa8yNMSPVAuM6w5I6LhaqEYRO8x02G8WPyE+8W+Q9m3SCFea59osg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.4.1.tgz", + "integrity": "sha512-cev6uUOiWH2KY4ozv17oxGkfonQ2oLDTlpcqU7HFntekUPwjEx0rOqaZPakGShxR6rb+GrBJ4Y7Vnf1bBk2Otg==", "license": "ISC", "dependencies": { "@fontsource/poppins": "^5.0.14", @@ -3424,9 +3424,9 @@ "license": "ISC" }, "node_modules/@intersect.mbo/pdf-ui": { - "version": "0.7.0-beta-24", - "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-24.tgz", - "integrity": "sha512-o/3thkna2DQjvtiSqMf4KHN2XgDQN8qHVRklF3VRVhPue8y99IWtbji0nhlvhoYDqmdEVL/3Nmrt9Xom3QjHwg==", + "version": "0.7.0-beta-25", + "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-25.tgz", + "integrity": "sha512-TDeWjJVMvLOR6sgTT6bCoHspZbybiRH0C5OzDDaU1yLSFD7xKx1aW5eAVdG0uzxrO+C0X7ceBGFoN5ucHICdlg==", "dependencies": { "@emurgo/cardano-serialization-lib-asmjs": "^12.0.0-beta.2", "@fontsource/poppins": "^5.0.14", diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index e9e3744b2..c02cfeab5 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -27,9 +27,9 @@ "@emotion/styled": "^11.11.0", "@emurgo/cardano-serialization-lib-asmjs": "^14.1.1", "@hookform/resolvers": "^3.3.1", - "@intersect.mbo/govtool-outcomes-pillar-ui": "1.4.0", + "@intersect.mbo/govtool-outcomes-pillar-ui": "1.4.1", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.7.0-beta-24", + "@intersect.mbo/pdf-ui": "0.7.0-beta-25", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@rollup/plugin-babel": "^6.0.4", diff --git a/govtool/frontend/yarn.lock b/govtool/frontend/yarn.lock index 14d5adf21..03cd99721 100644 --- a/govtool/frontend/yarn.lock +++ b/govtool/frontend/yarn.lock @@ -1492,10 +1492,10 @@ resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.4.tgz" integrity sha512-2MNFrDY8jkFYc9Il9DgLsHhMzuHnOYM1+CUYVWbzu9oT0hC7V7EcYvdCKeoll/Fcci04A+ERZ9wcc7cQ8lTkIA== -"@intersect.mbo/govtool-outcomes-pillar-ui@1.4.0": - version "1.4.0" - resolved "https://registry.npmjs.org/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.4.0.tgz" - integrity sha512-iSg6FzeUW4F3KSQDcHCytggCG68Q4OKUzQa8yNMSPVAuM6w5I6LhaqEYRO8x02G8WPyE+8W+Q9m3SCFea59osg== +"@intersect.mbo/govtool-outcomes-pillar-ui@1.4.1": + version "1.4.1" + resolved "https://registry.npmjs.org/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.4.1.tgz" + integrity sha512-cev6uUOiWH2KY4ozv17oxGkfonQ2oLDTlpcqU7HFntekUPwjEx0rOqaZPakGShxR6rb+GrBJ4Y7Vnf1bBk2Otg== dependencies: "@fontsource/poppins" "^5.0.14" "@intersect.mbo/intersectmbo.org-icons-set" "^1.0.8" @@ -1512,10 +1512,10 @@ resolved "https://registry.npmjs.org/@intersect.mbo/intersectmbo.org-icons-set/-/intersectmbo.org-icons-set-1.1.0.tgz" integrity sha512-sjKEtnK9eLYH/8kCD0YRQCms3byFA/tnSsei9NHTZbBYX9sBpeX6ErfR0sKYjOSxQOxl4FumX9D0X+vHIqxo8g== -"@intersect.mbo/pdf-ui@0.7.0-beta-24": - version "0.7.0-beta-24" - resolved "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-24.tgz" - integrity sha512-o/3thkna2DQjvtiSqMf4KHN2XgDQN8qHVRklF3VRVhPue8y99IWtbji0nhlvhoYDqmdEVL/3Nmrt9Xom3QjHwg== +"@intersect.mbo/pdf-ui@0.7.0-beta-25": + version "0.7.0-beta-25" + resolved "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-25.tgz" + integrity sha512-TDeWjJVMvLOR6sgTT6bCoHspZbybiRH0C5OzDDaU1yLSFD7xKx1aW5eAVdG0uzxrO+C0X7ceBGFoN5ucHICdlg== dependencies: "@emurgo/cardano-serialization-lib-asmjs" "^12.0.0-beta.2" "@fontsource/poppins" "^5.0.14" diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 000000000..e1ebe821d --- /dev/null +++ b/tests/README.md @@ -0,0 +1,26 @@ +# GovTool Tests + +This directory contains tests for the GovTool project. + +## 📍 Navigation + +- [Backend Tests](./govtool-backend/) +- [Frontend Tests](./govtool-frontend/playwright/) +- [Load Tests](./load-testing/) +- [Test Infrastructure](./test-infrastructure/) +- [Metadata API](./test-metadata-api/) + +## Backend Tests +- Conducts basic tests on GovTool backend endpoints using Python. + +## Frontend Tests +- Performs integration tests on the deployed GovTool platform using Playwright. + +## Load Tests +- Executes load tests on the GovTool API using Gatling. + +## Test Infrastructure +- Includes Docker Compose files and scripts to deploy and manage the GovTool test environment. + +## Metadata API +- A simple service to host JSON metadata during testing. \ No newline at end of file diff --git a/tests/cardano-test-wallet/index.js b/tests/cardano-test-wallet/index.js deleted file mode 100644 index 0221c9741..000000000 --- a/tests/cardano-test-wallet/index.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see index.js.LICENSE.txt */ -(()=>{var t={422:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.validateBasic=e.wNAF=void 0;const n=r(967),o=r(484),i=BigInt(0),s=BigInt(1);e.wNAF=function(t,e){const r=(t,e)=>{const r=e.negate();return t?r:e},n=t=>({windows:Math.ceil(e/t)+1,windowSize:2**(t-1)});return{constTimeNegate:r,unsafeLadder(e,r){let n=t.ZERO,o=e;for(;r>i;)r&s&&(n=n.add(o)),o=o.double(),r>>=s;return n},precomputeWindow(t,e){const{windows:r,windowSize:o}=n(e),i=[];let s=t,a=s;for(let t=0;t>=d,n>f&&(n-=h,i+=s);const a=e,p=e+Math.abs(n)-1,y=t%2!=0,g=n<0;0===n?c=c.add(r(y,o[a])):u=u.add(r(g,o[p]))}return{p:u,f:c}},wNAFCached(t,e,r,n){const o=t._WINDOW_SIZE||1;let i=e.get(t);return i||(i=this.precomputeWindow(t,o),1!==o&&e.set(t,n(i))),this.wNAF(o,i,r)}}},e.validateBasic=function(t){return(0,n.validateField)(t.Fp),(0,o.validateObject)(t,{n:"bigint",h:"bigint",Gx:"field",Gy:"field"},{nBitLength:"isSafeInteger",nByteLength:"isSafeInteger"}),Object.freeze({...(0,n.nLength)(t.n,t.nBitLength),...t,p:t.Fp.ORDER})}},377:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.twistedEdwards=void 0;const n=r(967),o=r(484),i=r(484),s=r(422),a=BigInt(0),f=BigInt(1),u=BigInt(2),c=BigInt(8),l={zip215:!0};e.twistedEdwards=function(t){const e=function(t){const e=(0,s.validateBasic)(t);return o.validateObject(t,{hash:"function",a:"bigint",d:"bigint",randomBytes:"function"},{adjustScalarBytes:"function",domain:"function",uvRatio:"function",mapToCurve:"function"}),Object.freeze({...e})}(t),{Fp:r,n:h,prehash:d,hash:p,randomBytes:y,nByteLength:g,h:b}=e,w=u<{try{return{isValid:!0,value:r.sqrt(t*r.inv(e))}}catch(t){return{isValid:!1,value:a}}}),B=e.adjustScalarBytes||(t=>t),x=e.domain||((t,e,r)=>{if(e.length||r)throw new Error("Contexts/pre-hash are not supported");return t}),v=t=>"bigint"==typeof t&&av(t)&&v(e)&&tt===a||A(t,w);function S(t,e){if(A(t,e))return t;throw new Error(`Expected valid scalar < ${e}, got ${typeof t} ${t}`)}function U(t){return t===a?t:S(t,h)}const O=new Map;function T(t){if(!(t instanceof k))throw new Error("ExtendedPoint expected")}class k{constructor(t,e,r,n){if(this.ex=t,this.ey=e,this.ez=r,this.et=n,!I(t))throw new Error("x required");if(!I(e))throw new Error("y required");if(!I(r))throw new Error("z required");if(!I(n))throw new Error("t required")}get x(){return this.toAffine().x}get y(){return this.toAffine().y}static fromAffine(t){if(t instanceof k)throw new Error("extended point not allowed");const{x:e,y:r}=t||{};if(!I(e)||!I(r))throw new Error("invalid affine point");return new k(e,r,f,m(e*r))}static normalizeZ(t){const e=r.invertBatch(t.map((t=>t.ez)));return t.map(((t,r)=>t.toAffine(e[r]))).map(k.fromAffine)}_setWindowSize(t){this._WINDOW_SIZE=t,O.delete(this)}assertValidity(){const{a:t,d:r}=e;if(this.is0())throw new Error("bad point: ZERO");const{ex:n,ey:o,ez:i,et:s}=this,a=m(n*n),f=m(o*o),u=m(i*i),c=m(u*u),l=m(a*t);if(m(u*m(l+f))!==m(c+m(r*m(a*f))))throw new Error("bad point: equation left != right (1)");if(m(n*o)!==m(i*s))throw new Error("bad point: equation left != right (2)")}equals(t){T(t);const{ex:e,ey:r,ez:n}=this,{ex:o,ey:i,ez:s}=t,a=m(e*s),f=m(o*n),u=m(r*s),c=m(i*n);return a===f&&u===c}is0(){return this.equals(k.ZERO)}negate(){return new k(m(-this.ex),this.ey,this.ez,m(-this.et))}double(){const{a:t}=e,{ex:r,ey:n,ez:o}=this,i=m(r*r),s=m(n*n),a=m(u*m(o*o)),f=m(t*i),c=r+n,l=m(m(c*c)-i-s),h=f+s,d=h-a,p=f-s,y=m(l*d),g=m(h*p),b=m(l*p),w=m(d*h);return new k(y,g,w,b)}add(t){T(t);const{a:r,d:n}=e,{ex:o,ey:i,ez:s,et:f}=this,{ex:c,ey:l,ez:h,et:d}=t;if(r===BigInt(-1)){const t=m((i-o)*(l+c)),e=m((i+o)*(l-c)),r=m(e-t);if(r===a)return this.double();const n=m(s*u*d),p=m(f*u*h),y=p+n,g=e+t,b=p-n,w=m(y*r),E=m(g*b),B=m(y*b),x=m(r*g);return new k(w,E,x,B)}const p=m(o*c),y=m(i*l),g=m(f*n*d),b=m(s*h),w=m((o+i)*(c+l)-p-y),E=b-g,B=b+g,x=m(y-r*p),v=m(w*E),A=m(B*x),I=m(w*x),S=m(E*B);return new k(v,A,S,I)}subtract(t){return this.add(t.negate())}wNAF(t){return _.wNAFCached(this,O,t,k.normalizeZ)}multiply(t){const{p:e,f:r}=this.wNAF(S(t,h));return k.normalizeZ([e,r])[0]}multiplyUnsafe(t){let e=U(t);return e===a?R:this.equals(R)||e===f?this:this.equals(L)?this.wNAF(e).p:_.unsafeLadder(this,e)}isSmallOrder(){return this.multiplyUnsafe(b).is0()}isTorsionFree(){return _.unsafeLadder(this,h).is0()}toAffine(t){const{ex:e,ey:n,ez:o}=this,i=this.is0();null==t&&(t=i?c:r.inv(o));const s=m(e*t),u=m(n*t),l=m(o*t);if(i)return{x:a,y:f};if(l!==f)throw new Error("invZ was invalid");return{x:s,y:u}}clearCofactor(){const{h:t}=e;return t===f?this:this.multiplyUnsafe(t)}static fromHex(t,n=!1){const{d:s,a:u}=e,c=r.BYTES,l=(t=(0,i.ensureBytes)("pointHex",t,c)).slice(),h=t[c-1];l[c-1]=-129&h;const d=o.bytesToNumberLE(l);d===a||S(d,n?w:r.ORDER);const p=m(d*d),y=m(p-f),g=m(s*p-u);let{isValid:b,value:B}=E(y,g);if(!b)throw new Error("Point.fromHex: invalid y coordinate");const x=(B&f)===f,v=0!=(128&h);if(!n&&B===a&&v)throw new Error("Point.fromHex: x=0 and x_0=1");return v!==x&&(B=m(-B)),k.fromAffine({x:B,y:d})}static fromPrivateKey(t){return j(t).point}toRawBytes(){const{x:t,y:e}=this.toAffine(),n=o.numberToBytesLE(e,r.BYTES);return n[n.length-1]|=t&f?128:0,n}toHex(){return o.bytesToHex(this.toRawBytes())}}k.BASE=new k(e.Gx,e.Gy,f,m(e.Gx*e.Gy)),k.ZERO=new k(a,f,f,a);const{BASE:L,ZERO:R}=k,_=(0,s.wNAF)(k,8*g);function M(t){return(0,n.mod)(t,h)}function C(t){return M(o.bytesToNumberLE(t))}function j(t){const e=g;t=(0,i.ensureBytes)("private key",t,e);const r=(0,i.ensureBytes)("hashed private key",p(t),2*e),n=B(r.slice(0,e)),o=r.slice(e,2*e),s=C(n),a=L.multiply(s),f=a.toRawBytes();return{head:n,prefix:o,scalar:s,point:a,pointBytes:f}}function N(t=new Uint8Array,...e){const r=o.concatBytes(...e);return C(p(x(r,(0,i.ensureBytes)("context",t),!!d)))}const P=l;return L._setWindowSize(8),{CURVE:e,getPublicKey:function(t){return j(t).pointBytes},sign:function(t,e,n={}){t=(0,i.ensureBytes)("message",t),d&&(t=d(t));const{prefix:s,scalar:a,pointBytes:f}=j(e),u=N(n.context,s,t),c=L.multiply(u).toRawBytes(),l=M(u+N(n.context,c,f,t)*a);U(l);const h=o.concatBytes(c,o.numberToBytesLE(l,r.BYTES));return(0,i.ensureBytes)("result",h,2*g)},verify:function(t,e,n,s=P){const{context:a,zip215:f}=s,u=r.BYTES;t=(0,i.ensureBytes)("signature",t,2*u),e=(0,i.ensureBytes)("message",e),d&&(e=d(e));const c=o.bytesToNumberLE(t.slice(u,2*u));let l,h,p;try{l=k.fromHex(n,f),h=k.fromHex(t.slice(0,u),f),p=L.multiplyUnsafe(c)}catch(t){return!1}if(!f&&l.isSmallOrder())return!1;const y=N(a,h.toRawBytes(),l.toRawBytes(),e);return h.add(l.multiplyUnsafe(y)).subtract(p).clearCofactor().equals(k.ZERO)},ExtendedPoint:k,utils:{getExtendedPublicKey:j,randomPrivateKey:()=>y(r.BYTES),precompute:(t=8,e=k.BASE)=>(e._setWindowSize(t),e.multiply(BigInt(3)),e)}}}},761:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.createHasher=e.isogenyMap=e.hash_to_field=e.expand_message_xof=e.expand_message_xmd=void 0;const n=r(967),o=r(484),i=o.bytesToNumberBE;function s(t,e){if(t<0||t>=1<<8*e)throw new Error(`bad I2OSP call: value=${t} length=${e}`);const r=Array.from({length:e}).fill(0);for(let n=e-1;n>=0;n--)r[n]=255&t,t>>>=8;return new Uint8Array(r)}function a(t,e){const r=new Uint8Array(t.length);for(let n=0;n255&&(e=n((0,o.concatBytes)((0,o.utf8ToBytes)("H2C-OVERSIZE-DST-"),e)));const{outputLen:i,blockLen:c}=n,l=Math.ceil(r/i);if(l>255)throw new Error("Invalid xmd length");const h=(0,o.concatBytes)(e,s(e.length,1)),d=s(0,c),p=s(r,2),y=new Array(l),g=n((0,o.concatBytes)(d,t,p,s(0,1),h));y[0]=n((0,o.concatBytes)(g,s(1,1),h));for(let t=1;t<=l;t++){const e=[a(g,y[t-1]),s(t+1,1),h];y[t]=n((0,o.concatBytes)(...e))}return(0,o.concatBytes)(...y).slice(0,r)}function l(t,e,r,n,i){if(f(t),f(e),u(r),e.length>255){const t=Math.ceil(2*n/8);e=i.create({dkLen:t}).update((0,o.utf8ToBytes)("H2C-OVERSIZE-DST-")).update(e).digest()}if(r>65535||e.length>255)throw new Error("expand_message_xof: invalid lenInBytes");return i.create({dkLen:r}).update(t).update(s(r,2)).update(e).update(s(e.length,1)).digest()}function h(t,e,r){(0,o.validateObject)(r,{DST:"stringOrUint8Array",p:"bigint",m:"isSafeInteger",k:"isSafeInteger",hash:"hash"});const{p:s,k:a,m:h,hash:d,expand:p,DST:y}=r;f(t),u(e);const g=function(t){if((0,o.isBytes)(t))return t;if("string"==typeof t)return(0,o.utf8ToBytes)(t);throw new Error("DST must be Uint8Array or string")}(y),b=s.toString(2).length,w=Math.ceil((b+a)/8),m=e*h*w;let E;if("xmd"===p)E=c(t,g,m,d);else if("xof"===p)E=l(t,g,m,a,d);else{if("_internal_pass"!==p)throw new Error('expand must be "xmd" or "xof"');E=t}const B=new Array(e);for(let t=0;tArray.from(t).reverse()));return(e,n)=>{const[o,i,s,a]=r.map((r=>r.reduce(((r,n)=>t.add(t.mul(r,e),n)))));return e=t.div(o,i),n=t.mul(n,t.div(s,a)),{x:e,y:n}}},e.createHasher=function(t,e,r){if("function"!=typeof e)throw new Error("mapToCurve() must be defined");return{hashToCurve(n,o){const i=h(n,2,{...r,DST:r.DST,...o}),s=t.fromAffine(e(i[0])),a=t.fromAffine(e(i[1])),f=s.add(a).clearCofactor();return f.assertValidity(),f},encodeToCurve(n,o){const i=h(n,1,{...r,DST:r.encodeDST,...o}),s=t.fromAffine(e(i[0])).clearCofactor();return s.assertValidity(),s}}}},967:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.mapHashToField=e.getMinHashLength=e.getFieldBytesLength=e.hashToPrivateScalar=e.FpSqrtEven=e.FpSqrtOdd=e.Field=e.nLength=e.FpIsSquare=e.FpDiv=e.FpInvertBatch=e.FpPow=e.validateField=e.isNegativeLE=e.FpSqrt=e.tonelliShanks=e.invert=e.pow2=e.pow=e.mod=void 0;const n=r(484),o=BigInt(0),i=BigInt(1),s=BigInt(2),a=BigInt(3),f=BigInt(4),u=BigInt(5),c=BigInt(8);function l(t,e){const r=t%e;return r>=o?r:e+r}function h(t,e,r){if(r<=o||e 0");if(r===i)return o;let n=i;for(;e>o;)e&i&&(n=n*t%r),t=t*t%r,e>>=i;return n}function d(t,e){if(t===o||e<=o)throw new Error(`invert: expected positive integers, got n=${t} mod=${e}`);let r=l(t,e),n=e,s=o,a=i,f=i,u=o;for(;r!==o;){const t=n/r,e=n%r,o=s-f*t,i=a-u*t;n=r,r=e,s=f,a=u,f=o,u=i}if(n!==i)throw new Error("invert: does not exist");return l(s,e)}function p(t){const e=(t-i)/s;let r,n,a;for(r=t-i,n=0;r%s===o;r/=s,n++);for(a=s;ao;)n*=n,n%=r;return n},e.invert=d,e.tonelliShanks=p,e.FpSqrt=y,e.isNegativeLE=(t,e)=>(l(t,e)&i)===i;const g=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function b(t,e,r){if(r 0");if(r===o)return t.ONE;if(r===i)return e;let n=t.ONE,s=e;for(;r>o;)r&i&&(n=t.mul(n,s)),s=t.sqr(s),r>>=i;return n}function w(t,e){const r=new Array(e.length),n=e.reduce(((e,n,o)=>t.is0(n)?e:(r[o]=e,t.mul(e,n))),t.ONE),o=t.inv(n);return e.reduceRight(((e,n,o)=>t.is0(n)?e:(r[o]=t.mul(e,r[o]),t.mul(e,n))),o),r}function m(t,e){const r=void 0!==e?e:t.toString(2).length;return{nBitLength:r,nByteLength:Math.ceil(r/8)}}function E(t){if("bigint"!=typeof t)throw new Error("field order must be bigint");const e=t.toString(2).length;return Math.ceil(e/8)}function B(t){const e=E(t);return e+Math.ceil(e/2)}e.validateField=function(t){const e=g.reduce(((t,e)=>(t[e]="function",t)),{ORDER:"bigint",MASK:"bigint",BYTES:"isSafeInteger",BITS:"isSafeInteger"});return(0,n.validateObject)(t,e)},e.FpPow=b,e.FpInvertBatch=w,e.FpDiv=function(t,e,r){return t.mul(e,"bigint"==typeof r?d(r,t.ORDER):t.inv(r))},e.FpIsSquare=function(t){const e=(t.ORDER-i)/s;return r=>{const n=t.pow(r,e);return t.eql(n,t.ZERO)||t.eql(n,t.ONE)}},e.nLength=m,e.Field=function(t,e,r=!1,s={}){if(t<=o)throw new Error(`Expected Field ORDER > 0, got ${t}`);const{nBitLength:a,nByteLength:f}=m(t,e);if(f>2048)throw new Error("Field lengths over 2048 bytes are not supported");const u=y(t),c=Object.freeze({ORDER:t,BITS:a,BYTES:f,MASK:(0,n.bitMask)(a),ZERO:o,ONE:i,create:e=>l(e,t),isValid:e=>{if("bigint"!=typeof e)throw new Error("Invalid field element: expected bigint, got "+typeof e);return o<=e&&et===o,isOdd:t=>(t&i)===i,neg:e=>l(-e,t),eql:(t,e)=>t===e,sqr:e=>l(e*e,t),add:(e,r)=>l(e+r,t),sub:(e,r)=>l(e-r,t),mul:(e,r)=>l(e*r,t),pow:(t,e)=>b(c,t,e),div:(e,r)=>l(e*d(r,t),t),sqrN:t=>t*t,addN:(t,e)=>t+e,subN:(t,e)=>t-e,mulN:(t,e)=>t*e,inv:e=>d(e,t),sqrt:s.sqrt||(t=>u(c,t)),invertBatch:t=>w(c,t),cmov:(t,e,r)=>r?e:t,toBytes:t=>r?(0,n.numberToBytesLE)(t,f):(0,n.numberToBytesBE)(t,f),fromBytes:t=>{if(t.length!==f)throw new Error(`Fp.fromBytes: expected ${f}, got ${t.length}`);return r?(0,n.bytesToNumberLE)(t):(0,n.bytesToNumberBE)(t)}});return Object.freeze(c)},e.FpSqrtOdd=function(t,e){if(!t.isOdd)throw new Error("Field doesn't have isOdd");const r=t.sqrt(e);return t.isOdd(r)?r:t.neg(r)},e.FpSqrtEven=function(t,e){if(!t.isOdd)throw new Error("Field doesn't have isOdd");const r=t.sqrt(e);return t.isOdd(r)?t.neg(r):r},e.hashToPrivateScalar=function(t,e,r=!1){const o=(t=(0,n.ensureBytes)("privateHash",t)).length,s=m(e).nByteLength+8;if(s<24||o1024)throw new Error(`hashToPrivateScalar: expected ${s}-1024 bytes of input, got ${o}`);return l(r?(0,n.bytesToNumberLE)(t):(0,n.bytesToNumberBE)(t),e-i)+i},e.getFieldBytesLength=E,e.getMinHashLength=B,e.mapHashToField=function(t,e,r=!1){const o=t.length,s=E(e),a=B(e);if(o<16||o1024)throw new Error(`expected ${a}-1024 bytes of input, got ${o}`);const f=l(r?(0,n.bytesToNumberBE)(t):(0,n.bytesToNumberLE)(t),e-i)+i;return r?(0,n.numberToBytesLE)(f,s):(0,n.numberToBytesBE)(f,s)}},854:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.montgomery=void 0;const n=r(967),o=r(484),i=BigInt(0),s=BigInt(1);e.montgomery=function(t){const e=(r=t,(0,o.validateObject)(r,{a:"bigint"},{montgomeryBits:"isSafeInteger",nByteLength:"isSafeInteger",adjustScalarBytes:"function",domain:"function",powPminus2:"function",Gu:"bigint"}),Object.freeze({...r}));var r;const{P:a}=e,f=t=>(0,n.mod)(t,a),u=e.montgomeryBits,c=Math.ceil(u/8),l=e.nByteLength,h=e.adjustScalarBytes||(t=>t),d=e.powPminus2||(t=>(0,n.pow)(t,a-BigInt(2),a));function p(t,e,r){const n=f(t*(e-r));return[e=f(e-n),r=f(r+n)]}function y(t){if("bigint"==typeof t&&i<=t&&t=i;t--){const e=n>>t&s;w^=e,a=p(w,c,h),c=a[0],h=a[1],a=p(w,l,b),l=a[0],b=a[1],w=e;const r=c+l,i=f(r*r),u=c-l,d=f(u*u),y=i-d,m=h+b,E=f((h-b)*r),B=f(m*u),x=E+B,v=E-B;h=f(x*x),b=f(o*f(v*v)),c=f(i*d),l=f(y*(i+f(g*y)))}a=p(w,c,h),c=a[0],h=a[1],a=p(w,l,b),l=a[0],b=a[1];const m=d(l);return f(c*m)}(r,function(t){const e=(0,o.ensureBytes)("scalar",t),r=e.length;if(r!==c&&r!==l)throw new Error(`Expected ${c} or ${l} bytes, got ${r}`);return(0,o.bytesToNumberLE)(h(e))}(t));if(n===i)throw new Error("Invalid private or public key received");return b(n)}const m=b(e.Gu);function E(t){return w(t,m)}return{scalarMult:w,scalarMultBase:E,getSharedSecret:(t,e)=>w(t,e),getPublicKey:t=>E(t),utils:{randomPrivateKey:()=>e.randomBytes(e.nByteLength)},GuBytes:m}}},484:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.validateObject=e.createHmacDrbg=e.bitMask=e.bitSet=e.bitGet=e.bitLen=e.utf8ToBytes=e.equalBytes=e.concatBytes=e.ensureBytes=e.numberToVarBytesBE=e.numberToBytesLE=e.numberToBytesBE=e.bytesToNumberLE=e.bytesToNumberBE=e.hexToBytes=e.hexToNumber=e.numberToHexUnpadded=e.bytesToHex=e.isBytes=void 0;const r=BigInt(0),n=BigInt(1),o=BigInt(2);function i(t){return t instanceof Uint8Array||null!=t&&"object"==typeof t&&"Uint8Array"===t.constructor.name}e.isBytes=i;const s=Array.from({length:256},((t,e)=>e.toString(16).padStart(2,"0")));function a(t){if(!i(t))throw new Error("Uint8Array expected");let e="";for(let r=0;r=c._0&&t<=c._9?t-c._0:t>=c._A&&t<=c._F?t-(c._A-10):t>=c._a&&t<=c._f?t-(c._a-10):void 0}function h(t){if("string"!=typeof t)throw new Error("hex string expected, got "+typeof t);const e=t.length,r=e/2;if(e%2)throw new Error("padded hex string expected, got unpadded hex of length "+e);const n=new Uint8Array(r);for(let e=0,o=0;er;t>>=n,e+=1);return e},e.bitGet=function(t,e){return t>>BigInt(e)&n},e.bitSet=(t,e,o)=>t|(o?n:r)<(o<new Uint8Array(t),g=t=>Uint8Array.from(t);e.createHmacDrbg=function(t,e,r){if("number"!=typeof t||t<2)throw new Error("hashLen must be a number");if("number"!=typeof e||e<2)throw new Error("qByteLen must be a number");if("function"!=typeof r)throw new Error("hmacFn must be a function");let n=y(t),o=y(t),i=0;const s=()=>{n.fill(1),o.fill(0),i=0},a=(...t)=>r(o,n,...t),f=(t=y())=>{o=a(g([0]),t),n=a(),0!==t.length&&(o=a(g([1]),t),n=a())},u=()=>{if(i++>=1e3)throw new Error("drbg: tried 1000 values");let t=0;const r=[];for(;t{let r;for(s(),f(t);!(r=e(u()));)f();return s(),r}};const b={bigint:t=>"bigint"==typeof t,function:t=>"function"==typeof t,boolean:t=>"boolean"==typeof t,string:t=>"string"==typeof t,stringOrUint8Array:t=>"string"==typeof t||i(t),isSafeInteger:t=>Number.isSafeInteger(t),array:t=>Array.isArray(t),field:(t,e)=>e.Fp.isValid(t),hash:t=>"function"==typeof t&&Number.isSafeInteger(t.outputLen)};e.validateObject=function(t,e,r={}){const n=(e,r,n)=>{const o=b[r];if("function"!=typeof o)throw new Error(`Invalid validator "${r}", expected function`);const i=t[e];if(!(n&&void 0===i||o(i,t)))throw new Error(`Invalid param ${String(e)}=${i} (${typeof i}), expected ${r}`)};for(const[t,r]of Object.entries(e))n(t,r,!1);for(const[t,e]of Object.entries(r))n(t,e,!0);return t}},459:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.hash_to_ristretto255=e.hashToRistretto255=e.RistrettoPoint=e.encodeToCurve=e.hashToCurve=e.edwardsToMontgomeryPriv=e.edwardsToMontgomery=e.edwardsToMontgomeryPub=e.x25519=e.ed25519ph=e.ed25519ctx=e.ed25519=e.ED25519_TORSION_SUBGROUP=void 0;const n=r(102),o=r(175),i=r(377),s=r(854),a=r(967),f=r(484),u=r(761),c=BigInt("57896044618658097711785492504343953926634992332820282019728792003956564819949"),l=BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752"),h=BigInt(0),d=BigInt(1),p=BigInt(2),y=BigInt(5),g=BigInt(10),b=BigInt(20),w=BigInt(40),m=BigInt(80);function E(t){const e=c,r=t*t%e*t%e,n=(0,a.pow2)(r,p,e)*r%e,o=(0,a.pow2)(n,d,e)*t%e,i=(0,a.pow2)(o,y,e)*o%e,s=(0,a.pow2)(i,g,e)*i%e,f=(0,a.pow2)(s,b,e)*s%e,u=(0,a.pow2)(f,w,e)*f%e,l=(0,a.pow2)(u,m,e)*u%e,h=(0,a.pow2)(l,m,e)*u%e,E=(0,a.pow2)(h,g,e)*i%e;return{pow_p_5_8:(0,a.pow2)(E,p,e)*t%e,b2:r}}function B(t){return t[0]&=248,t[31]&=127,t[31]|=64,t}function x(t,e){const r=c,n=(0,a.mod)(e*e*e,r),o=E(t*(0,a.mod)(n*n*e,r)).pow_p_5_8;let i=(0,a.mod)(t*n*o,r);const s=(0,a.mod)(e*i*i,r),f=i,u=(0,a.mod)(i*l,r),h=s===t,d=s===(0,a.mod)(-t,r),p=s===(0,a.mod)(-t*l,r);return h&&(i=f),(d||p)&&(i=u),(0,a.isNegativeLE)(i,r)&&(i=(0,a.mod)(-i,r)),{isValid:h||d,value:i}}e.ED25519_TORSION_SUBGROUP=["0100000000000000000000000000000000000000000000000000000000000000","c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a","0000000000000000000000000000000000000000000000000000000000000080","26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05","ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f","26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85","0000000000000000000000000000000000000000000000000000000000000000","c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa"];const v=(0,a.Field)(c,void 0,!0),A={a:BigInt(-1),d:BigInt("37095705934669439343138083508754565189542113879843219016388785533085940283555"),Fp:v,n:BigInt("7237005577332262213973186563042994240857116359379907606001950938285454250989"),h:BigInt(8),Gx:BigInt("15112221349535400772501151409588531511454012693041857206046113283949847762202"),Gy:BigInt("46316835694926478169428394003475163141307993866256225615783033603165251855960"),hash:n.sha512,randomBytes:o.randomBytes,adjustScalarBytes:B,uvRatio:x};function I(t,e,r){if(e.length>255)throw new Error("Context is too big");return(0,o.concatBytes)((0,o.utf8ToBytes)("SigEd25519 no Ed25519 collisions"),new Uint8Array([r?1:0,e.length]),e,t)}function S(t){const{y:r}=e.ed25519.ExtendedPoint.fromHex(t),n=BigInt(1);return v.toBytes(v.create((n+r)*v.inv(n-r)))}e.ed25519=(0,i.twistedEdwards)(A),e.ed25519ctx=(0,i.twistedEdwards)({...A,domain:I}),e.ed25519ph=(0,i.twistedEdwards)({...A,domain:I,prehash:n.sha512}),e.x25519=(0,s.montgomery)({P:c,a:BigInt(486662),montgomeryBits:255,nByteLength:32,Gu:BigInt(9),powPminus2:t=>{const e=c,{pow_p_5_8:r,b2:n}=E(t);return(0,a.mod)((0,a.pow2)(r,BigInt(3),e)*n,e)},adjustScalarBytes:B,randomBytes:o.randomBytes}),e.edwardsToMontgomeryPub=S,e.edwardsToMontgomery=S,e.edwardsToMontgomeryPriv=function(t){const e=A.hash(t.subarray(0,32));return A.adjustScalarBytes(e).subarray(0,32)};const U=(v.ORDER+BigInt(3))/BigInt(8),O=v.pow(p,U),T=v.sqrt(v.neg(v.ONE)),k=(v.ORDER-BigInt(5))/BigInt(8),L=BigInt(486662),R=(0,a.FpSqrtEven)(v,v.neg(BigInt(486664)));const _=(()=>(0,u.createHasher)(e.ed25519.ExtendedPoint,(t=>function(t){const{xMn:e,xMd:r,yMn:n,yMd:o}=function(t){let e=v.sqr(t);e=v.mul(e,p);let r=v.add(e,v.ONE),n=v.neg(L),o=v.sqr(r),i=v.mul(o,r),s=v.mul(e,L);s=v.mul(s,n),s=v.add(s,o),s=v.mul(s,n);let a=v.sqr(i);o=v.sqr(a),a=v.mul(a,i),a=v.mul(a,s),o=v.mul(o,a);let f=v.pow(o,k);f=v.mul(f,a);let u=v.mul(f,T);o=v.sqr(f),o=v.mul(o,i);let c=v.eql(o,s),l=v.cmov(u,f,c),h=v.mul(n,e),y=v.mul(f,t);y=v.mul(y,O);let g=v.mul(y,T),b=v.mul(s,e);o=v.sqr(y),o=v.mul(o,i);let w=v.eql(o,b),m=v.cmov(g,y,w);o=v.sqr(l),o=v.mul(o,i);let E=v.eql(o,s),B=v.cmov(h,n,E),x=v.cmov(m,l,E),A=v.isOdd(x);return x=v.cmov(x,v.neg(x),E!==A),{xMn:B,xMd:r,yMn:x,yMd:d}}(t);let i=v.mul(e,o);i=v.mul(i,R);let s=v.mul(r,n),a=v.sub(e,r),f=v.add(e,r),u=v.mul(s,f),c=v.eql(u,v.ZERO);i=v.cmov(i,v.ZERO,c),s=v.cmov(s,v.ONE,c),a=v.cmov(a,v.ONE,c),f=v.cmov(f,v.ONE,c);const l=v.invertBatch([s,f]);return{x:v.mul(i,l[0]),y:v.mul(a,l[1])}}(t[0])),{DST:"edwards25519_XMD:SHA-512_ELL2_RO_",encodeDST:"edwards25519_XMD:SHA-512_ELL2_NU_",p:v.ORDER,m:1,k:128,expand:"xmd",hash:n.sha512}))();function M(t){if(!(t instanceof $))throw new Error("RistrettoPoint expected")}e.hashToCurve=_.hashToCurve,e.encodeToCurve=_.encodeToCurve;const C=l,j=BigInt("25063068953384623474111414158702152701244531502492656460079210482610430750235"),N=BigInt("54469307008909316920995813868745141605393597292927456921205312896311721017578"),P=BigInt("1159843021668779879193775521855586647937357759715417654439879720876111806838"),F=BigInt("40440834346308536858101042469323190826248399146238708352240133220865137265952"),H=t=>x(d,t),D=BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),V=t=>e.ed25519.CURVE.Fp.create((0,f.bytesToNumberLE)(t)&D);function q(t){const{d:r}=e.ed25519.CURVE,n=e.ed25519.CURVE.Fp.ORDER,o=e.ed25519.CURVE.Fp.create,i=o(C*t*t),s=o((i+d)*P);let f=BigInt(-1);const u=o((f-r*i)*o(i+r));let{isValid:c,value:l}=x(s,u),h=o(l*t);(0,a.isNegativeLE)(h,n)||(h=o(-h)),c||(l=h),c||(f=i);const p=o(f*(i-d)*F-u),y=l*l,g=o((l+l)*u),b=o(p*j),w=o(d-y),m=o(d+y);return new e.ed25519.ExtendedPoint(o(g*m),o(w*b),o(b*m),o(g*w))}class ${constructor(t){this.ep=t}static fromAffine(t){return new $(e.ed25519.ExtendedPoint.fromAffine(t))}static hashToCurve(t){t=(0,f.ensureBytes)("ristrettoHash",t,64);const e=q(V(t.slice(0,32))),r=q(V(t.slice(32,64)));return new $(e.add(r))}static fromHex(t){t=(0,f.ensureBytes)("ristrettoHex",t,32);const{a:r,d:n}=e.ed25519.CURVE,o=e.ed25519.CURVE.Fp.ORDER,i=e.ed25519.CURVE.Fp.create,s="RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint",u=V(t);if(!(0,f.equalBytes)((0,f.numberToBytesLE)(u,32),t)||(0,a.isNegativeLE)(u,o))throw new Error(s);const c=i(u*u),l=i(d+r*c),p=i(d-r*c),y=i(l*l),g=i(p*p),b=i(r*n*y-g),{isValid:w,value:m}=H(i(b*g)),E=i(m*p),B=i(m*E*b);let x=i((u+u)*E);(0,a.isNegativeLE)(x,o)&&(x=i(-x));const v=i(l*B),A=i(x*v);if(!w||(0,a.isNegativeLE)(A,o)||v===h)throw new Error(s);return new $(new e.ed25519.ExtendedPoint(x,v,d,A))}toRawBytes(){let{ex:t,ey:r,ez:n,et:o}=this.ep;const i=e.ed25519.CURVE.Fp.ORDER,s=e.ed25519.CURVE.Fp.create,u=s(s(n+r)*s(n-r)),c=s(t*r),l=s(c*c),{value:h}=H(s(u*l)),d=s(h*u),p=s(h*c),y=s(d*p*o);let g;if((0,a.isNegativeLE)(o*y,i)){let e=s(r*C),n=s(t*C);t=e,r=n,g=s(d*N)}else g=p;(0,a.isNegativeLE)(t*y,i)&&(r=s(-r));let b=s((n-r)*g);return(0,a.isNegativeLE)(b,i)&&(b=s(-b)),(0,f.numberToBytesLE)(b,32)}toHex(){return(0,f.bytesToHex)(this.toRawBytes())}toString(){return this.toHex()}equals(t){M(t);const{ex:r,ey:n}=this.ep,{ex:o,ey:i}=t.ep,s=e.ed25519.CURVE.Fp.create,a=s(r*i)===s(n*o),f=s(n*i)===s(r*o);return a||f}add(t){return M(t),new $(this.ep.add(t.ep))}subtract(t){return M(t),new $(this.ep.subtract(t.ep))}multiply(t){return new $(this.ep.multiply(t))}multiplyUnsafe(t){return new $(this.ep.multiplyUnsafe(t))}double(){return new $(this.ep.double())}negate(){return new $(this.ep.negate())}}e.RistrettoPoint=($.BASE||($.BASE=new $(e.ed25519.ExtendedPoint.BASE)),$.ZERO||($.ZERO=new $(e.ed25519.ExtendedPoint.ZERO)),$),e.hashToRistretto255=(t,e)=>{const r=e.DST,i="string"==typeof r?(0,o.utf8ToBytes)(r):r,s=(0,u.expand_message_xmd)(t,i,64,n.sha512);return $.hashToCurve(s)},e.hash_to_ristretto255=e.hashToRistretto255},557:(t,e)=>{"use strict";function r(t){if(!Number.isSafeInteger(t)||t<0)throw new Error(`Wrong positive integer: ${t}`)}function n(t){if("boolean"!=typeof t)throw new Error(`Expected boolean, not ${t}`)}function o(t,...e){if(!((r=t)instanceof Uint8Array||null!=r&&"object"==typeof r&&"Uint8Array"===r.constructor.name))throw new Error("Expected Uint8Array");var r;if(e.length>0&&!e.includes(t.length))throw new Error(`Expected Uint8Array of length ${e}, not of length=${t.length}`)}function i(t){if("function"!=typeof t||"function"!=typeof t.create)throw new Error("Hash should be wrapped by utils.wrapConstructor");r(t.outputLen),r(t.blockLen)}function s(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function a(t,e){o(t);const r=e.outputLen;if(t.length{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.SHA2=void 0;const n=r(557),o=r(175);class i extends o.Hash{constructor(t,e,r,n){super(),this.blockLen=t,this.outputLen=e,this.padOffset=r,this.isLE=n,this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.buffer=new Uint8Array(t),this.view=(0,o.createView)(this.buffer)}update(t){(0,n.exists)(this);const{view:e,buffer:r,blockLen:i}=this,s=(t=(0,o.toBytes)(t)).length;for(let n=0;ni-a&&(this.process(r,0),a=0);for(let t=a;t>o&i),a=Number(r&i),f=n?4:0,u=n?0:4;t.setUint32(e+f,s,n),t.setUint32(e+u,a,n)}(r,i-8,BigInt(8*this.length),s),this.process(r,0);const f=(0,o.createView)(t),u=this.outputLen;if(u%4)throw new Error("_sha2: outputLen should be aligned to 32bit");const c=u/4,l=this.get();if(c>l.length)throw new Error("_sha2: outputLen bigger than state");for(let t=0;t{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.add5L=e.add5H=e.add4H=e.add4L=e.add3H=e.add3L=e.add=e.rotlBL=e.rotlBH=e.rotlSL=e.rotlSH=e.rotr32L=e.rotr32H=e.rotrBL=e.rotrBH=e.rotrSL=e.rotrSH=e.shrSL=e.shrSH=e.toBig=e.split=e.fromBig=void 0;const r=BigInt(2**32-1),n=BigInt(32);function o(t,e=!1){return e?{h:Number(t&r),l:Number(t>>n&r)}:{h:0|Number(t>>n&r),l:0|Number(t&r)}}function i(t,e=!1){let r=new Uint32Array(t.length),n=new Uint32Array(t.length);for(let i=0;iBigInt(t>>>0)<>>0);e.toBig=s;const a=(t,e,r)=>t>>>r;e.shrSH=a;const f=(t,e,r)=>t<<32-r|e>>>r;e.shrSL=f;const u=(t,e,r)=>t>>>r|e<<32-r;e.rotrSH=u;const c=(t,e,r)=>t<<32-r|e>>>r;e.rotrSL=c;const l=(t,e,r)=>t<<64-r|e>>>r-32;e.rotrBH=l;const h=(t,e,r)=>t>>>r-32|e<<64-r;e.rotrBL=h;const d=(t,e)=>e;e.rotr32H=d;const p=(t,e)=>t;e.rotr32L=p;const y=(t,e,r)=>t<>>32-r;e.rotlSH=y;const g=(t,e,r)=>e<>>32-r;e.rotlSL=g;const b=(t,e,r)=>e<>>64-r;e.rotlBH=b;const w=(t,e,r)=>t<>>64-r;function m(t,e,r,n){const o=(e>>>0)+(n>>>0);return{h:t+r+(o/2**32|0)|0,l:0|o}}e.rotlBL=w,e.add=m;const E=(t,e,r)=>(t>>>0)+(e>>>0)+(r>>>0);e.add3L=E;const B=(t,e,r,n)=>e+r+n+(t/2**32|0)|0;e.add3H=B;const x=(t,e,r,n)=>(t>>>0)+(e>>>0)+(r>>>0)+(n>>>0);e.add4L=x;const v=(t,e,r,n,o)=>e+r+n+o+(t/2**32|0)|0;e.add4H=v;const A=(t,e,r,n,o)=>(t>>>0)+(e>>>0)+(r>>>0)+(n>>>0)+(o>>>0);e.add5L=A;const I=(t,e,r,n,o,i)=>e+r+n+o+i+(t/2**32|0)|0;e.add5H=I;const S={fromBig:o,split:i,toBig:s,shrSH:a,shrSL:f,rotrSH:u,rotrSL:c,rotrBH:l,rotrBL:h,rotr32H:d,rotr32L:p,rotlSH:y,rotlSL:g,rotlBH:b,rotlBL:w,add:m,add3L:E,add3H:B,add4L:x,add4H:v,add5H:I,add5L:A};e.default=S},145:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.crypto=void 0,e.crypto="object"==typeof globalThis&&"crypto"in globalThis?globalThis.crypto:void 0},102:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.sha384=e.sha512_256=e.sha512_224=e.sha512=e.SHA512=void 0;const n=r(915),o=r(318),i=r(175),[s,a]=(()=>o.default.split(["0x428a2f98d728ae22","0x7137449123ef65cd","0xb5c0fbcfec4d3b2f","0xe9b5dba58189dbbc","0x3956c25bf348b538","0x59f111f1b605d019","0x923f82a4af194f9b","0xab1c5ed5da6d8118","0xd807aa98a3030242","0x12835b0145706fbe","0x243185be4ee4b28c","0x550c7dc3d5ffb4e2","0x72be5d74f27b896f","0x80deb1fe3b1696b1","0x9bdc06a725c71235","0xc19bf174cf692694","0xe49b69c19ef14ad2","0xefbe4786384f25e3","0x0fc19dc68b8cd5b5","0x240ca1cc77ac9c65","0x2de92c6f592b0275","0x4a7484aa6ea6e483","0x5cb0a9dcbd41fbd4","0x76f988da831153b5","0x983e5152ee66dfab","0xa831c66d2db43210","0xb00327c898fb213f","0xbf597fc7beef0ee4","0xc6e00bf33da88fc2","0xd5a79147930aa725","0x06ca6351e003826f","0x142929670a0e6e70","0x27b70a8546d22ffc","0x2e1b21385c26c926","0x4d2c6dfc5ac42aed","0x53380d139d95b3df","0x650a73548baf63de","0x766a0abb3c77b2a8","0x81c2c92e47edaee6","0x92722c851482353b","0xa2bfe8a14cf10364","0xa81a664bbc423001","0xc24b8b70d0f89791","0xc76c51a30654be30","0xd192e819d6ef5218","0xd69906245565a910","0xf40e35855771202a","0x106aa07032bbd1b8","0x19a4c116b8d2d0c8","0x1e376c085141ab53","0x2748774cdf8eeb99","0x34b0bcb5e19b48a8","0x391c0cb3c5c95a63","0x4ed8aa4ae3418acb","0x5b9cca4f7763e373","0x682e6ff3d6b2b8a3","0x748f82ee5defb2fc","0x78a5636f43172f60","0x84c87814a1f0ab72","0x8cc702081a6439ec","0x90befffa23631e28","0xa4506cebde82bde9","0xbef9a3f7b2c67915","0xc67178f2e372532b","0xca273eceea26619c","0xd186b8c721c0c207","0xeada7dd6cde0eb1e","0xf57d4f7fee6ed178","0x06f067aa72176fba","0x0a637dc5a2c898a6","0x113f9804bef90dae","0x1b710b35131c471b","0x28db77f523047d84","0x32caab7b40c72493","0x3c9ebe0a15c9bebc","0x431d67c49c100d4c","0x4cc5d4becb3e42b6","0x597f299cfc657e2a","0x5fcb6fab3ad6faec","0x6c44198c4a475817"].map((t=>BigInt(t)))))(),f=new Uint32Array(80),u=new Uint32Array(80);class c extends n.SHA2{constructor(){super(128,64,16,!1),this.Ah=1779033703,this.Al=-205731576,this.Bh=-1150833019,this.Bl=-2067093701,this.Ch=1013904242,this.Cl=-23791573,this.Dh=-1521486534,this.Dl=1595750129,this.Eh=1359893119,this.El=-1377402159,this.Fh=-1694144372,this.Fl=725511199,this.Gh=528734635,this.Gl=-79577749,this.Hh=1541459225,this.Hl=327033209}get(){const{Ah:t,Al:e,Bh:r,Bl:n,Ch:o,Cl:i,Dh:s,Dl:a,Eh:f,El:u,Fh:c,Fl:l,Gh:h,Gl:d,Hh:p,Hl:y}=this;return[t,e,r,n,o,i,s,a,f,u,c,l,h,d,p,y]}set(t,e,r,n,o,i,s,a,f,u,c,l,h,d,p,y){this.Ah=0|t,this.Al=0|e,this.Bh=0|r,this.Bl=0|n,this.Ch=0|o,this.Cl=0|i,this.Dh=0|s,this.Dl=0|a,this.Eh=0|f,this.El=0|u,this.Fh=0|c,this.Fl=0|l,this.Gh=0|h,this.Gl=0|d,this.Hh=0|p,this.Hl=0|y}process(t,e){for(let r=0;r<16;r++,e+=4)f[r]=t.getUint32(e),u[r]=t.getUint32(e+=4);for(let t=16;t<80;t++){const e=0|f[t-15],r=0|u[t-15],n=o.default.rotrSH(e,r,1)^o.default.rotrSH(e,r,8)^o.default.shrSH(e,r,7),i=o.default.rotrSL(e,r,1)^o.default.rotrSL(e,r,8)^o.default.shrSL(e,r,7),s=0|f[t-2],a=0|u[t-2],c=o.default.rotrSH(s,a,19)^o.default.rotrBH(s,a,61)^o.default.shrSH(s,a,6),l=o.default.rotrSL(s,a,19)^o.default.rotrBL(s,a,61)^o.default.shrSL(s,a,6),h=o.default.add4L(i,l,u[t-7],u[t-16]),d=o.default.add4H(h,n,c,f[t-7],f[t-16]);f[t]=0|d,u[t]=0|h}let{Ah:r,Al:n,Bh:i,Bl:c,Ch:l,Cl:h,Dh:d,Dl:p,Eh:y,El:g,Fh:b,Fl:w,Gh:m,Gl:E,Hh:B,Hl:x}=this;for(let t=0;t<80;t++){const e=o.default.rotrSH(y,g,14)^o.default.rotrSH(y,g,18)^o.default.rotrBH(y,g,41),v=o.default.rotrSL(y,g,14)^o.default.rotrSL(y,g,18)^o.default.rotrBL(y,g,41),A=y&b^~y&m,I=g&w^~g&E,S=o.default.add5L(x,v,I,a[t],u[t]),U=o.default.add5H(S,B,e,A,s[t],f[t]),O=0|S,T=o.default.rotrSH(r,n,28)^o.default.rotrBH(r,n,34)^o.default.rotrBH(r,n,39),k=o.default.rotrSL(r,n,28)^o.default.rotrBL(r,n,34)^o.default.rotrBL(r,n,39),L=r&i^r&l^i&l,R=n&c^n&h^c&h;B=0|m,x=0|E,m=0|b,E=0|w,b=0|y,w=0|g,({h:y,l:g}=o.default.add(0|d,0|p,0|U,0|O)),d=0|l,p=0|h,l=0|i,h=0|c,i=0|r,c=0|n;const _=o.default.add3L(O,k,R);r=o.default.add3H(_,U,T,L),n=0|_}({h:r,l:n}=o.default.add(0|this.Ah,0|this.Al,0|r,0|n)),({h:i,l:c}=o.default.add(0|this.Bh,0|this.Bl,0|i,0|c)),({h:l,l:h}=o.default.add(0|this.Ch,0|this.Cl,0|l,0|h)),({h:d,l:p}=o.default.add(0|this.Dh,0|this.Dl,0|d,0|p)),({h:y,l:g}=o.default.add(0|this.Eh,0|this.El,0|y,0|g)),({h:b,l:w}=o.default.add(0|this.Fh,0|this.Fl,0|b,0|w)),({h:m,l:E}=o.default.add(0|this.Gh,0|this.Gl,0|m,0|E)),({h:B,l:x}=o.default.add(0|this.Hh,0|this.Hl,0|B,0|x)),this.set(r,n,i,c,l,h,d,p,y,g,b,w,m,E,B,x)}roundClean(){f.fill(0),u.fill(0)}destroy(){this.buffer.fill(0),this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)}}e.SHA512=c;class l extends c{constructor(){super(),this.Ah=-1942145080,this.Al=424955298,this.Bh=1944164710,this.Bl=-1982016298,this.Ch=502970286,this.Cl=855612546,this.Dh=1738396948,this.Dl=1479516111,this.Eh=258812777,this.El=2077511080,this.Fh=2011393907,this.Fl=79989058,this.Gh=1067287976,this.Gl=1780299464,this.Hh=286451373,this.Hl=-1848208735,this.outputLen=28}}class h extends c{constructor(){super(),this.Ah=573645204,this.Al=-64227540,this.Bh=-1621794909,this.Bl=-934517566,this.Ch=596883563,this.Cl=1867755857,this.Dh=-1774684391,this.Dl=1497426621,this.Eh=-1775747358,this.El=-1467023389,this.Fh=-1101128155,this.Fl=1401305490,this.Gh=721525244,this.Gl=746961066,this.Hh=246885852,this.Hl=-2117784414,this.outputLen=32}}class d extends c{constructor(){super(),this.Ah=-876896931,this.Al=-1056596264,this.Bh=1654270250,this.Bl=914150663,this.Ch=-1856437926,this.Cl=812702999,this.Dh=355462360,this.Dl=-150054599,this.Eh=1731405415,this.El=-4191439,this.Fh=-1900787065,this.Fl=1750603025,this.Gh=-619958771,this.Gl=1694076839,this.Hh=1203062813,this.Hl=-1090891868,this.outputLen=48}}e.sha512=(0,i.wrapConstructor)((()=>new c)),e.sha512_224=(0,i.wrapConstructor)((()=>new l)),e.sha512_256=(0,i.wrapConstructor)((()=>new h)),e.sha384=(0,i.wrapConstructor)((()=>new d))},175:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.randomBytes=e.wrapXOFConstructorWithOpts=e.wrapConstructorWithOpts=e.wrapConstructor=e.checkOpts=e.Hash=e.concatBytes=e.toBytes=e.utf8ToBytes=e.asyncLoop=e.nextTick=e.hexToBytes=e.bytesToHex=e.isLE=e.rotr=e.createView=e.u32=e.u8=void 0;const n=r(145);function o(t){return t instanceof Uint8Array||null!=t&&"object"==typeof t&&"Uint8Array"===t.constructor.name}if(e.u8=t=>new Uint8Array(t.buffer,t.byteOffset,t.byteLength),e.u32=t=>new Uint32Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/4)),e.createView=t=>new DataView(t.buffer,t.byteOffset,t.byteLength),e.rotr=(t,e)=>t<<32-e|t>>>e,e.isLE=68===new Uint8Array(new Uint32Array([287454020]).buffer)[0],!e.isLE)throw new Error("Non little-endian hardware is not supported");const i=Array.from({length:256},((t,e)=>e.toString(16).padStart(2,"0")));e.bytesToHex=function(t){if(!o(t))throw new Error("Uint8Array expected");let e="";for(let r=0;r=s&&t<=a?t-s:t>=f&&t<=u?t-(f-10):t>=c&&t<=l?t-(c-10):void 0}function d(t){if("string"!=typeof t)throw new Error("utf8ToBytes expected string, got "+typeof t);return new Uint8Array((new TextEncoder).encode(t))}function p(t){if("string"==typeof t&&(t=d(t)),!o(t))throw new Error("expected Uint8Array, got "+typeof t);return t}e.hexToBytes=function(t){if("string"!=typeof t)throw new Error("hex string expected, got "+typeof t);const e=t.length,r=e/2;if(e%2)throw new Error("padded hex string expected, got unpadded hex of length "+e);const n=new Uint8Array(r);for(let e=0,o=0;e{},e.asyncLoop=async function(t,r,n){let o=Date.now();for(let i=0;i=0&&tt().update(p(e)).digest(),r=t();return e.outputLen=r.outputLen,e.blockLen=r.blockLen,e.create=()=>t(),e},e.wrapConstructorWithOpts=function(t){const e=(e,r)=>t(r).update(p(e)).digest(),r=t({});return e.outputLen=r.outputLen,e.blockLen=r.blockLen,e.create=e=>t(e),e},e.wrapXOFConstructorWithOpts=function(t){const e=(e,r)=>t(r).update(p(e)).digest(),r=t({});return e.outputLen=r.outputLen,e.blockLen=r.blockLen,e.create=e=>t(e),e},e.randomBytes=function(t=32){if(n.crypto&&"function"==typeof n.crypto.getRandomValues)return n.crypto.getRandomValues(new Uint8Array(t));throw new Error("crypto.getRandomValues must be defined")}},526:(t,e)=>{"use strict";e.byteLength=function(t){var e=a(t),r=e[0],n=e[1];return 3*(r+n)/4-n},e.toByteArray=function(t){var e,r,i=a(t),s=i[0],f=i[1],u=new o(function(t,e,r){return 3*(e+r)/4-r}(0,s,f)),c=0,l=f>0?s-4:s;for(r=0;r>16&255,u[c++]=e>>8&255,u[c++]=255&e;return 2===f&&(e=n[t.charCodeAt(r)]<<2|n[t.charCodeAt(r+1)]>>4,u[c++]=255&e),1===f&&(e=n[t.charCodeAt(r)]<<10|n[t.charCodeAt(r+1)]<<4|n[t.charCodeAt(r+2)]>>2,u[c++]=e>>8&255,u[c++]=255&e),u},e.fromByteArray=function(t){for(var e,n=t.length,o=n%3,i=[],s=16383,a=0,u=n-o;au?u:a+s));return 1===o?(e=t[n-1],i.push(r[e>>2]+r[e<<4&63]+"==")):2===o&&(e=(t[n-2]<<8)+t[n-1],i.push(r[e>>10]+r[e>>4&63]+r[e<<2&63]+"=")),i.join("")};for(var r=[],n=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0;s<64;++s)r[s]=i[s],n[i.charCodeAt(s)]=s;function a(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");return-1===r&&(r=e),[r,r===e?0:4-r%4]}function f(t,e,n){for(var o,i,s=[],a=e;a>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return s.join("")}n["-".charCodeAt(0)]=62,n["_".charCodeAt(0)]=63},343:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.bech32m=e.bech32=void 0;const r="qpzry9x8gf2tvdw0s3jn54khce6mua7l",n={};for(let t=0;t<32;t++){const e=r.charAt(t);n[e]=t}function o(t){const e=t>>25;return(33554431&t)<<5^996825010&-(e>>0&1)^642813549&-(e>>1&1)^513874426&-(e>>2&1)^1027748829&-(e>>3&1)^705979059&-(e>>4&1)}function i(t){let e=1;for(let r=0;r126)return"Invalid prefix ("+t+")";e=o(e)^n>>5}e=o(e);for(let r=0;r=r;)i-=r,a.push(o>>i&s);if(n)i>0&&a.push(o<=e)return"Excess padding";if(o<r)return"Exceeds length limit";const s=t.toLowerCase(),a=t.toUpperCase();if(t!==s&&t!==a)return"Mixed-case string "+t;const f=(t=s).lastIndexOf("1");if(-1===f)return"No separator character for "+t;if(0===f)return"Missing prefix for "+t;const u=t.slice(0,f),c=t.slice(f+1);if(c.length<6)return"Data too short";let l=i(u);if("string"==typeof l)return l;const h=[];for(let t=0;t=c.length||h.push(r)}return l!==e?"Invalid checksum for "+t:{prefix:u,words:h}}return e="bech32"===t?1:734539939,{decodeUnsafe:function(t,e){const r=s(t,e);if("object"==typeof r)return r},decode:function(t,e){const r=s(t,e);if("object"==typeof r)return r;throw new Error(r)},encode:function(t,n,s){if(s=s||90,t.length+7+n.length>s)throw new TypeError("Exceeds length limit");let a=i(t=t.toLowerCase());if("string"==typeof a)throw new Error(a);let f=t+"1";for(let t=0;t>5!=0)throw new Error("Non 5-bit word");a=o(a)^e,f+=r.charAt(e)}for(let t=0;t<6;++t)a=o(a);a^=e;for(let t=0;t<6;++t)f+=r.charAt(a>>5*(5-t)&31);return f},toWords:a,fromWordsUnsafe:f,fromWords:u}}e.bech32=c("bech32"),e.bech32m=c("bech32m")},156:(t,e,r)=>{const n=r(829);function o(t,e,r){const n=t[e]+t[r];let o=t[e+1]+t[r+1];n>=4294967296&&o++,t[e]=n,t[e+1]=o}function i(t,e,r,n){let o=t[e]+r;r<0&&(o+=4294967296);let i=t[e+1]+n;o>=4294967296&&i++,t[e]=o,t[e+1]=i}function s(t,e){return t[e]^t[e+1]<<8^t[e+2]<<16^t[e+3]<<24}function a(t,e,r,n,s,a){const f=l[s],u=l[s+1],h=l[a],d=l[a+1];o(c,t,e),i(c,t,f,u);let p=c[n]^c[t],y=c[n+1]^c[t+1];c[n]=y,c[n+1]=p,o(c,r,n),p=c[e]^c[r],y=c[e+1]^c[r+1],c[e]=p>>>24^y<<8,c[e+1]=y>>>24^p<<8,o(c,t,e),i(c,t,h,d),p=c[n]^c[t],y=c[n+1]^c[t+1],c[n]=p>>>16^y<<16,c[n+1]=y>>>16^p<<16,o(c,r,n),p=c[e]^c[r],y=c[e+1]^c[r+1],c[e]=y>>>31^p<<1,c[e+1]=p>>>31^y<<1}const f=new Uint32Array([4089235720,1779033703,2227873595,3144134277,4271175723,1013904242,1595750129,2773480762,2917565137,1359893119,725511199,2600822924,4215389547,528734635,327033209,1541459225]),u=new Uint8Array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3,11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4,7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8,9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13,2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9,12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11,13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10,6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5,10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3].map((function(t){return 2*t}))),c=new Uint32Array(32),l=new Uint32Array(32);function h(t,e){let r=0;for(r=0;r<16;r++)c[r]=t.h[r],c[r+16]=f[r];for(c[24]=c[24]^t.t,c[25]=c[25]^t.t/4294967296,e&&(c[28]=~c[28],c[29]=~c[29]),r=0;r<32;r++)l[r]=s(t.b,4*r);for(r=0;r<12;r++)a(0,8,16,24,u[16*r+0],u[16*r+1]),a(2,10,18,26,u[16*r+2],u[16*r+3]),a(4,12,20,28,u[16*r+4],u[16*r+5]),a(6,14,22,30,u[16*r+6],u[16*r+7]),a(0,10,20,30,u[16*r+8],u[16*r+9]),a(2,12,22,24,u[16*r+10],u[16*r+11]),a(4,14,16,26,u[16*r+12],u[16*r+13]),a(6,8,18,28,u[16*r+14],u[16*r+15]);for(r=0;r<16;r++)t.h[r]=t.h[r]^c[r]^c[r+16]}const d=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);function p(t,e,r,n){if(0===t||t>64)throw new Error("Illegal output length, expected 0 < length <= 64");if(e&&e.length>64)throw new Error("Illegal key, expected Uint8Array with 0 < length <= 64");if(r&&16!==r.length)throw new Error("Illegal salt, expected Uint8Array with length is 16");if(n&&16!==n.length)throw new Error("Illegal personal, expected Uint8Array with length is 16");const o={b:new Uint8Array(128),h:new Uint32Array(16),t:0,c:0,outlen:t};d.fill(0),d[0]=t,e&&(d[1]=e.length),d[2]=1,d[3]=1,r&&d.set(r,32),n&&d.set(n,48);for(let t=0;t<16;t++)o.h[t]=f[t]^s(d,4*t);return e&&(y(o,e),o.c=128),o}function y(t,e){for(let r=0;r>2]>>8*(3&r);return e}function b(t,e,r,o,i){r=r||64,t=n.normalizeInput(t),o&&(o=n.normalizeInput(o)),i&&(i=n.normalizeInput(i));const s=p(r,e,o,i);return y(s,t),g(s)}t.exports={blake2b:b,blake2bHex:function(t,e,r,o,i){const s=b(t,e,r,o,i);return n.toHex(s)},blake2bInit:p,blake2bUpdate:y,blake2bFinal:g}},843:(t,e,r)=>{const n=r(829);function o(t,e){return t[e]^t[e+1]<<8^t[e+2]<<16^t[e+3]<<24}function i(t,e,r,n,o,i){u[t]=u[t]+u[e]+o,u[n]=s(u[n]^u[t],16),u[r]=u[r]+u[n],u[e]=s(u[e]^u[r],12),u[t]=u[t]+u[e]+i,u[n]=s(u[n]^u[t],8),u[r]=u[r]+u[n],u[e]=s(u[e]^u[r],7)}function s(t,e){return t>>>e^t<<32-e}const a=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),f=new Uint8Array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3,11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4,7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8,9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13,2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9,12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11,13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10,6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5,10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0]),u=new Uint32Array(16),c=new Uint32Array(16);function l(t,e){let r=0;for(r=0;r<8;r++)u[r]=t.h[r],u[r+8]=a[r];for(u[12]^=t.t,u[13]^=t.t/4294967296,e&&(u[14]=~u[14]),r=0;r<16;r++)c[r]=o(t.b,4*r);for(r=0;r<10;r++)i(0,4,8,12,c[f[16*r+0]],c[f[16*r+1]]),i(1,5,9,13,c[f[16*r+2]],c[f[16*r+3]]),i(2,6,10,14,c[f[16*r+4]],c[f[16*r+5]]),i(3,7,11,15,c[f[16*r+6]],c[f[16*r+7]]),i(0,5,10,15,c[f[16*r+8]],c[f[16*r+9]]),i(1,6,11,12,c[f[16*r+10]],c[f[16*r+11]]),i(2,7,8,13,c[f[16*r+12]],c[f[16*r+13]]),i(3,4,9,14,c[f[16*r+14]],c[f[16*r+15]]);for(r=0;r<8;r++)t.h[r]^=u[r]^u[r+8]}function h(t,e){if(!(t>0&&t<=32))throw new Error("Incorrect output length, should be in [1, 32]");const r=e?e.length:0;if(e&&!(r>0&&r<=32))throw new Error("Incorrect key length, should be in [1, 32]");const n={h:new Uint32Array(a),b:new Uint8Array(64),c:0,t:0,outlen:t};return n.h[0]^=16842752^r<<8^t,r>0&&(d(n,e),n.c=64),n}function d(t,e){for(let r=0;r>2]>>8*(3&r)&255;return e}function y(t,e,r){r=r||32,t=n.normalizeInput(t);const o=h(r,e);return d(o,t),p(o)}t.exports={blake2s:y,blake2sHex:function(t,e,r){const o=y(t,e,r);return n.toHex(o)},blake2sInit:h,blake2sUpdate:d,blake2sFinal:p}},493:(t,e,r)=>{const n=r(156),o=r(843);t.exports={blake2b:n.blake2b,blake2bHex:n.blake2bHex,blake2bInit:n.blake2bInit,blake2bUpdate:n.blake2bUpdate,blake2bFinal:n.blake2bFinal,blake2s:o.blake2s,blake2sHex:o.blake2sHex,blake2sInit:o.blake2sInit,blake2sUpdate:o.blake2sUpdate,blake2sFinal:o.blake2sFinal}},829:t=>{function e(t){return(4294967296+t).toString(16).substring(1)}t.exports={normalizeInput:function(t){let e;if(t instanceof Uint8Array)e=t;else{if("string"!=typeof t)throw new Error("Input must be an string, Buffer or Uint8Array");e=(new TextEncoder).encode(t)}return e},toHex:function(t){return Array.prototype.map.call(t,(function(t){return(t<16?"0":"")+t.toString(16)})).join("")},debugPrint:function(t,r,n){let o="\n"+t+" = ";for(let i=0;i{"use strict";const n=r(526),o=r(251),i="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;e.Buffer=f,e.SlowBuffer=function(t){return+t!=t&&(t=0),f.alloc(+t)},e.INSPECT_MAX_BYTES=50;const s=2147483647;function a(t){if(t>s)throw new RangeError('The value "'+t+'" is invalid for option "size"');const e=new Uint8Array(t);return Object.setPrototypeOf(e,f.prototype),e}function f(t,e,r){if("number"==typeof t){if("string"==typeof e)throw new TypeError('The "string" argument must be of type string. Received type number');return l(t)}return u(t,e,r)}function u(t,e,r){if("string"==typeof t)return function(t,e){if("string"==typeof e&&""!==e||(e="utf8"),!f.isEncoding(e))throw new TypeError("Unknown encoding: "+e);const r=0|y(t,e);let n=a(r);const o=n.write(t,e);return o!==r&&(n=n.slice(0,o)),n}(t,e);if(ArrayBuffer.isView(t))return function(t){if(Z(t,Uint8Array)){const e=new Uint8Array(t);return d(e.buffer,e.byteOffset,e.byteLength)}return h(t)}(t);if(null==t)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t);if(Z(t,ArrayBuffer)||t&&Z(t.buffer,ArrayBuffer))return d(t,e,r);if("undefined"!=typeof SharedArrayBuffer&&(Z(t,SharedArrayBuffer)||t&&Z(t.buffer,SharedArrayBuffer)))return d(t,e,r);if("number"==typeof t)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=t.valueOf&&t.valueOf();if(null!=n&&n!==t)return f.from(n,e,r);const o=function(t){if(f.isBuffer(t)){const e=0|p(t.length),r=a(e);return 0===r.length||t.copy(r,0,0,e),r}return void 0!==t.length?"number"!=typeof t.length||J(t.length)?a(0):h(t):"Buffer"===t.type&&Array.isArray(t.data)?h(t.data):void 0}(t);if(o)return o;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof t[Symbol.toPrimitive])return f.from(t[Symbol.toPrimitive]("string"),e,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t)}function c(t){if("number"!=typeof t)throw new TypeError('"size" argument must be of type number');if(t<0)throw new RangeError('The value "'+t+'" is invalid for option "size"')}function l(t){return c(t),a(t<0?0:0|p(t))}function h(t){const e=t.length<0?0:0|p(t.length),r=a(e);for(let n=0;n=s)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s.toString(16)+" bytes");return 0|t}function y(t,e){if(f.isBuffer(t))return t.length;if(ArrayBuffer.isView(t)||Z(t,ArrayBuffer))return t.byteLength;if("string"!=typeof t)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof t);const r=t.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;let o=!1;for(;;)switch(e){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return W(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return z(t).length;default:if(o)return n?-1:W(t).length;e=(""+e).toLowerCase(),o=!0}}function g(t,e,r){let n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return k(this,e,r);case"utf8":case"utf-8":return S(this,e,r);case"ascii":return O(this,e,r);case"latin1":case"binary":return T(this,e,r);case"base64":return I(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return L(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function b(t,e,r){const n=t[e];t[e]=t[r],t[r]=n}function w(t,e,r,n,o){if(0===t.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),J(r=+r)&&(r=o?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(o)return-1;r=t.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof e&&(e=f.from(e,n)),f.isBuffer(e))return 0===e.length?-1:m(t,e,r,n,o);if("number"==typeof e)return e&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):m(t,[e],r,n,o);throw new TypeError("val must be string, number or Buffer")}function m(t,e,r,n,o){let i,s=1,a=t.length,f=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;s=2,a/=2,f/=2,r/=2}function u(t,e){return 1===s?t[e]:t.readUInt16BE(e*s)}if(o){let n=-1;for(i=r;ia&&(r=a-f),i=r;i>=0;i--){let r=!0;for(let n=0;no&&(n=o):n=o;const i=e.length;let s;for(n>i/2&&(n=i/2),s=0;s>8,o=r%256,i.push(o),i.push(n);return i}(e,t.length-r),t,r,n)}function I(t,e,r){return 0===e&&r===t.length?n.fromByteArray(t):n.fromByteArray(t.slice(e,r))}function S(t,e,r){r=Math.min(t.length,r);const n=[];let o=e;for(;o239?4:e>223?3:e>191?2:1;if(o+s<=r){let r,n,a,f;switch(s){case 1:e<128&&(i=e);break;case 2:r=t[o+1],128==(192&r)&&(f=(31&e)<<6|63&r,f>127&&(i=f));break;case 3:r=t[o+1],n=t[o+2],128==(192&r)&&128==(192&n)&&(f=(15&e)<<12|(63&r)<<6|63&n,f>2047&&(f<55296||f>57343)&&(i=f));break;case 4:r=t[o+1],n=t[o+2],a=t[o+3],128==(192&r)&&128==(192&n)&&128==(192&a)&&(f=(15&e)<<18|(63&r)<<12|(63&n)<<6|63&a,f>65535&&f<1114112&&(i=f))}}null===i?(i=65533,s=1):i>65535&&(i-=65536,n.push(i>>>10&1023|55296),i=56320|1023&i),n.push(i),o+=s}return function(t){const e=t.length;if(e<=U)return String.fromCharCode.apply(String,t);let r="",n=0;for(;nn.length?(f.isBuffer(e)||(e=f.from(e)),e.copy(n,o)):Uint8Array.prototype.set.call(n,e,o);else{if(!f.isBuffer(e))throw new TypeError('"list" argument must be an Array of Buffers');e.copy(n,o)}o+=e.length}return n},f.byteLength=y,f.prototype._isBuffer=!0,f.prototype.swap16=function(){const t=this.length;if(t%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let e=0;er&&(t+=" ... "),""},i&&(f.prototype[i]=f.prototype.inspect),f.prototype.compare=function(t,e,r,n,o){if(Z(t,Uint8Array)&&(t=f.from(t,t.offset,t.byteLength)),!f.isBuffer(t))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof t);if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),e<0||r>t.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&e>=r)return 0;if(n>=o)return-1;if(e>=r)return 1;if(this===t)return 0;let i=(o>>>=0)-(n>>>=0),s=(r>>>=0)-(e>>>=0);const a=Math.min(i,s),u=this.slice(n,o),c=t.slice(e,r);for(let t=0;t>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}const o=this.length-e;if((void 0===r||r>o)&&(r=o),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let i=!1;for(;;)switch(n){case"hex":return E(this,t,e,r);case"utf8":case"utf-8":return B(this,t,e,r);case"ascii":case"latin1":case"binary":return x(this,t,e,r);case"base64":return v(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return A(this,t,e,r);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},f.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const U=4096;function O(t,e,r){let n="";r=Math.min(t.length,r);for(let o=e;on)&&(r=n);let o="";for(let n=e;nr)throw new RangeError("Trying to access beyond buffer length")}function _(t,e,r,n,o,i){if(!f.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>o||et.length)throw new RangeError("Index out of range")}function M(t,e,r,n,o){V(e,n,o,t,r,7);let i=Number(e&BigInt(4294967295));t[r++]=i,i>>=8,t[r++]=i,i>>=8,t[r++]=i,i>>=8,t[r++]=i;let s=Number(e>>BigInt(32)&BigInt(4294967295));return t[r++]=s,s>>=8,t[r++]=s,s>>=8,t[r++]=s,s>>=8,t[r++]=s,r}function C(t,e,r,n,o){V(e,n,o,t,r,7);let i=Number(e&BigInt(4294967295));t[r+7]=i,i>>=8,t[r+6]=i,i>>=8,t[r+5]=i,i>>=8,t[r+4]=i;let s=Number(e>>BigInt(32)&BigInt(4294967295));return t[r+3]=s,s>>=8,t[r+2]=s,s>>=8,t[r+1]=s,s>>=8,t[r]=s,r+8}function j(t,e,r,n,o,i){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function N(t,e,r,n,i){return e=+e,r>>>=0,i||j(t,0,r,4),o.write(t,e,r,n,23,4),r+4}function P(t,e,r,n,i){return e=+e,r>>>=0,i||j(t,0,r,8),o.write(t,e,r,n,52,8),r+8}f.prototype.slice=function(t,e){const r=this.length;(t=~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),(e=void 0===e?r:~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),e>>=0,e>>>=0,r||R(t,e,this.length);let n=this[t],o=1,i=0;for(;++i>>=0,e>>>=0,r||R(t,e,this.length);let n=this[t+--e],o=1;for(;e>0&&(o*=256);)n+=this[t+--e]*o;return n},f.prototype.readUint8=f.prototype.readUInt8=function(t,e){return t>>>=0,e||R(t,1,this.length),this[t]},f.prototype.readUint16LE=f.prototype.readUInt16LE=function(t,e){return t>>>=0,e||R(t,2,this.length),this[t]|this[t+1]<<8},f.prototype.readUint16BE=f.prototype.readUInt16BE=function(t,e){return t>>>=0,e||R(t,2,this.length),this[t]<<8|this[t+1]},f.prototype.readUint32LE=f.prototype.readUInt32LE=function(t,e){return t>>>=0,e||R(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},f.prototype.readUint32BE=f.prototype.readUInt32BE=function(t,e){return t>>>=0,e||R(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},f.prototype.readBigUInt64LE=X((function(t){q(t>>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||$(t,this.length-8);const n=e+256*this[++t]+65536*this[++t]+this[++t]*2**24,o=this[++t]+256*this[++t]+65536*this[++t]+r*2**24;return BigInt(n)+(BigInt(o)<>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||$(t,this.length-8);const n=e*2**24+65536*this[++t]+256*this[++t]+this[++t],o=this[++t]*2**24+65536*this[++t]+256*this[++t]+r;return(BigInt(n)<>>=0,e>>>=0,r||R(t,e,this.length);let n=this[t],o=1,i=0;for(;++i=o&&(n-=Math.pow(2,8*e)),n},f.prototype.readIntBE=function(t,e,r){t>>>=0,e>>>=0,r||R(t,e,this.length);let n=e,o=1,i=this[t+--n];for(;n>0&&(o*=256);)i+=this[t+--n]*o;return o*=128,i>=o&&(i-=Math.pow(2,8*e)),i},f.prototype.readInt8=function(t,e){return t>>>=0,e||R(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},f.prototype.readInt16LE=function(t,e){t>>>=0,e||R(t,2,this.length);const r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt16BE=function(t,e){t>>>=0,e||R(t,2,this.length);const r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt32LE=function(t,e){return t>>>=0,e||R(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},f.prototype.readInt32BE=function(t,e){return t>>>=0,e||R(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},f.prototype.readBigInt64LE=X((function(t){q(t>>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||$(t,this.length-8);const n=this[t+4]+256*this[t+5]+65536*this[t+6]+(r<<24);return(BigInt(n)<>>=0,"offset");const e=this[t],r=this[t+7];void 0!==e&&void 0!==r||$(t,this.length-8);const n=(e<<24)+65536*this[++t]+256*this[++t]+this[++t];return(BigInt(n)<>>=0,e||R(t,4,this.length),o.read(this,t,!0,23,4)},f.prototype.readFloatBE=function(t,e){return t>>>=0,e||R(t,4,this.length),o.read(this,t,!1,23,4)},f.prototype.readDoubleLE=function(t,e){return t>>>=0,e||R(t,8,this.length),o.read(this,t,!0,52,8)},f.prototype.readDoubleBE=function(t,e){return t>>>=0,e||R(t,8,this.length),o.read(this,t,!1,52,8)},f.prototype.writeUintLE=f.prototype.writeUIntLE=function(t,e,r,n){t=+t,e>>>=0,r>>>=0,n||_(this,t,e,r,Math.pow(2,8*r)-1,0);let o=1,i=0;for(this[e]=255&t;++i>>=0,r>>>=0,n||_(this,t,e,r,Math.pow(2,8*r)-1,0);let o=r-1,i=1;for(this[e+o]=255&t;--o>=0&&(i*=256);)this[e+o]=t/i&255;return e+r},f.prototype.writeUint8=f.prototype.writeUInt8=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,1,255,0),this[e]=255&t,e+1},f.prototype.writeUint16LE=f.prototype.writeUInt16LE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,2,65535,0),this[e]=255&t,this[e+1]=t>>>8,e+2},f.prototype.writeUint16BE=f.prototype.writeUInt16BE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,2,65535,0),this[e]=t>>>8,this[e+1]=255&t,e+2},f.prototype.writeUint32LE=f.prototype.writeUInt32LE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,4,4294967295,0),this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t,e+4},f.prototype.writeUint32BE=f.prototype.writeUInt32BE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,4,4294967295,0),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},f.prototype.writeBigUInt64LE=X((function(t,e=0){return M(this,t,e,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeBigUInt64BE=X((function(t,e=0){return C(this,t,e,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e>>>=0,!n){const n=Math.pow(2,8*r-1);_(this,t,e,r,n-1,-n)}let o=0,i=1,s=0;for(this[e]=255&t;++o>0)-s&255;return e+r},f.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e>>>=0,!n){const n=Math.pow(2,8*r-1);_(this,t,e,r,n-1,-n)}let o=r-1,i=1,s=0;for(this[e+o]=255&t;--o>=0&&(i*=256);)t<0&&0===s&&0!==this[e+o+1]&&(s=1),this[e+o]=(t/i>>0)-s&255;return e+r},f.prototype.writeInt8=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,1,127,-128),t<0&&(t=255+t+1),this[e]=255&t,e+1},f.prototype.writeInt16LE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,2,32767,-32768),this[e]=255&t,this[e+1]=t>>>8,e+2},f.prototype.writeInt16BE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,2,32767,-32768),this[e]=t>>>8,this[e+1]=255&t,e+2},f.prototype.writeInt32LE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,4,2147483647,-2147483648),this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24,e+4},f.prototype.writeInt32BE=function(t,e,r){return t=+t,e>>>=0,r||_(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},f.prototype.writeBigInt64LE=X((function(t,e=0){return M(this,t,e,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeBigInt64BE=X((function(t,e=0){return C(this,t,e,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeFloatLE=function(t,e,r){return N(this,t,e,!0,r)},f.prototype.writeFloatBE=function(t,e,r){return N(this,t,e,!1,r)},f.prototype.writeDoubleLE=function(t,e,r){return P(this,t,e,!0,r)},f.prototype.writeDoubleBE=function(t,e,r){return P(this,t,e,!1,r)},f.prototype.copy=function(t,e,r,n){if(!f.isBuffer(t))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e>>=0,r=void 0===r?this.length:r>>>0,t||(t=0),"number"==typeof t)for(o=e;o=n+4;r-=3)e=`_${t.slice(r-3,r)}${e}`;return`${t.slice(0,r)}${e}`}function V(t,e,r,n,o,i){if(t>r||t3?0===e||e===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(i+1)}${n}`:`>= -(2${n} ** ${8*(i+1)-1}${n}) and < 2 ** ${8*(i+1)-1}${n}`:`>= ${e}${n} and <= ${r}${n}`,new F.ERR_OUT_OF_RANGE("value",o,t)}!function(t,e,r){q(e,"offset"),void 0!==t[e]&&void 0!==t[e+r]||$(e,t.length-(r+1))}(n,o,i)}function q(t,e){if("number"!=typeof t)throw new F.ERR_INVALID_ARG_TYPE(e,"number",t)}function $(t,e,r){if(Math.floor(t)!==t)throw q(t,r),new F.ERR_OUT_OF_RANGE(r||"offset","an integer",t);if(e<0)throw new F.ERR_BUFFER_OUT_OF_BOUNDS;throw new F.ERR_OUT_OF_RANGE(r||"offset",`>= ${r?1:0} and <= ${e}`,t)}H("ERR_BUFFER_OUT_OF_BOUNDS",(function(t){return t?`${t} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),H("ERR_INVALID_ARG_TYPE",(function(t,e){return`The "${t}" argument must be of type number. Received type ${typeof e}`}),TypeError),H("ERR_OUT_OF_RANGE",(function(t,e,r){let n=`The value of "${t}" is out of range.`,o=r;return Number.isInteger(r)&&Math.abs(r)>2**32?o=D(String(r)):"bigint"==typeof r&&(o=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(o=D(o)),o+="n"),n+=` It must be ${e}. Received ${o}`,n}),RangeError);const K=/[^+/0-9A-Za-z-_]/g;function W(t,e){let r;e=e||1/0;const n=t.length;let o=null;const i=[];for(let s=0;s55295&&r<57344){if(!o){if(r>56319){(e-=3)>-1&&i.push(239,191,189);continue}if(s+1===n){(e-=3)>-1&&i.push(239,191,189);continue}o=r;continue}if(r<56320){(e-=3)>-1&&i.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(e-=3)>-1&&i.push(239,191,189);if(o=null,r<128){if((e-=1)<0)break;i.push(r)}else if(r<2048){if((e-=2)<0)break;i.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;i.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;i.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return i}function z(t){return n.toByteArray(function(t){if((t=(t=t.split("=")[0]).trim().replace(K,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function G(t,e,r,n){let o;for(o=0;o=e.length||o>=t.length);++o)e[o+r]=t[o];return o}function Z(t,e){return t instanceof e||null!=t&&null!=t.constructor&&null!=t.constructor.name&&t.constructor.name===e.name}function J(t){return t!=t}const Y=function(){const t="0123456789abcdef",e=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let o=0;o<16;++o)e[n+o]=t[r]+t[o]}return e}();function X(t){return"undefined"==typeof BigInt?Q:t}function Q(){throw new Error("BigInt not supported")}},251:(t,e)=>{e.read=function(t,e,r,n,o){var i,s,a=8*o-n-1,f=(1<>1,c=-7,l=r?o-1:0,h=r?-1:1,d=t[e+l];for(l+=h,i=d&(1<<-c)-1,d>>=-c,c+=a;c>0;i=256*i+t[e+l],l+=h,c-=8);for(s=i&(1<<-c)-1,i>>=-c,c+=n;c>0;s=256*s+t[e+l],l+=h,c-=8);if(0===i)i=1-u;else{if(i===f)return s?NaN:1/0*(d?-1:1);s+=Math.pow(2,n),i-=u}return(d?-1:1)*s*Math.pow(2,i-n)},e.write=function(t,e,r,n,o,i){var s,a,f,u=8*i-o-1,c=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,d=n?0:i-1,p=n?1:-1,y=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(a=isNaN(e)?1:0,s=c):(s=Math.floor(Math.log(e)/Math.LN2),e*(f=Math.pow(2,-s))<1&&(s--,f*=2),(e+=s+l>=1?h/f:h*Math.pow(2,1-l))*f>=2&&(s++,f/=2),s+l>=c?(a=0,s=c):s+l>=1?(a=(e*f-1)*Math.pow(2,o),s+=l):(a=e*Math.pow(2,l-1)*Math.pow(2,o),s=0));o>=8;t[r+d]=255&a,d+=p,a/=256,o-=8);for(s=s<0;t[r+d]=255&s,d+=p,s/=256,u-=8);t[r+d-p]|=128*y}},92:(t,e,r)=>{"use strict";var n=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==r.g)return r.g;throw new Error("unable to locate global object")}();t.exports=e=n.fetch,n.fetch&&(e.default=n.fetch.bind(n)),e.Headers=n.Headers,e.Request=n.Request,e.Response=n.Response},374:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.mkCardanoWalletExtension=e.mkCip95Wallet=void 0;const n=r(493),o=r(329),i=r(772),s=r(353),a=r(329),f=r(493),u=r(287),c=new a.Encoder({mapsAsObjects:!1,useRecords:!1}),l=new a.Decoder({mapsAsObjects:!1});class h{constructor(t){this.value=t}}async function d(t,e){const r=e.networkId??0,o=t.addressBech32(r);console.debug("Wallet address:"+o);const i=u.Buffer.from(t.addressRawBytes(r)),a=i.toString("hex"),h=u.Buffer.from(t.rewardAddressRawBytes(r)).toString("hex"),d=u.Buffer.from(t.stakeKey.public).toString("hex");return{getBalance:async()=>(await s.default.queryUtxos(o),"0"),submitTx:async t=>(console.debug("[CardanoWallet] SubmittingTx: ",t),await s.default.submitTransaction(t).then((async e=>function(t){let e=l.decode(u.Buffer.from(t,"hex"));const r=Uint8Array.from(c.encode(e[0]));return(0,f.blake2bHex)(r,void 0,32)}(t)))),getUtxos:(t,e)=>p(o,i,t,e),getUsedAddresses:async()=>[a],getUnusedAddresses:async()=>[a],getChangeAddress:async()=>a,getRewardAddresses:async()=>[h,...e.extraRewardAddresses??[]],getNetworkId:async()=>r,experimental:{on:(t,e)=>{},off:(t,e)=>{},getCollateral:()=>""},cip95:{getPubDRepKey:async()=>d,getUnregisteredPubStakeKeys:async()=>[d],getRegisteredPubStakeKeys:async()=>[d,...e.extraRegisteredPubStakeKeys??[]]},getActivePubStakeKeys:async()=>[h],signTx:async(r,o)=>{let i=l.decode(u.Buffer.from(r,"hex"));const s=u.Buffer.from(c.encode(i)).toString("hex");r!=s&&(console.warn("[CardanoWallet] Re-encoded tx is not same"),console.warn("[CardanoWallet] Starting Tx",r),console.warn("[CardanoWallet] Re-Encoded Tx",s));const a=Uint8Array.from(c.encode(i[0])),f=n.blake2b(a,void 0,32);console.debug("[CardanoWallet] Signing Tx hash="+u.Buffer.from(f).toString("hex"));const h=await t.paymentKey.signRaw(f),d=new Map,p=[[t.paymentKey.public,h]];if(e.enableStakeSigning){console.debug("Signing stake key...");const e=await t.stakeKey.signRaw(f);p.push([t.stakeKey.public,e])}return d.set(0,p),u.Buffer.from(c.encode(d)).toString("hex")},signData:async(t,e)=>"",getExtensions:()=>[{cip:95}]}}(0,o.addExtension)({Class:h,tag:259,encode:(t,e)=>e(t.value),decode:t=>new h(t)}),e.mkCip95Wallet=d,e.mkCardanoWalletExtension=async function(){let t=!1;return{apiVersion:"1.3.1",icon:"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg viewBox='0 0 500 500' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='309.36' y='12.441' width='121.115' height='472.347' style='fill: rgb(128 177 211)%3B'/%3E%3Cellipse style='fill: rgb(128 177 211)%3B' cx='231.272' cy='320.966' rx='171.791' ry='137.051'/%3E%3C/svg%3E",enable:async function(){const e=window.cardanoTestWallet.wallet||(await i.ShelleyWallet.generate()).json(),r=window.cardanoTestWallet.config||{};return t=!0,await d(i.ShelleyWallet.fromJson(e),r)},isEnabled:async function(){return t},name:"Demos",supportedExtensions:[{cip:95}]}};const p=async(t,e,r,n)=>{function o(t){const e=BigInt(t.lovelace);let r=new Map;for(let e in t){const n=t[e];for(let t in n)if(r.has(e))r.get(e).set(t,BigInt(n[t]));else{let o=new Map;o.set(t,BigInt(n[t])),r.set(e,o)}}return r.size>0?[e,r]:e}return(await s.default.queryUtxos(t)).map((t=>{const r=t.txin.split("#");return u.Buffer.from(c.encode([[u.Buffer.from(r[0],"hex"),BigInt(r[1])],[e,o(t.value)]])).toString("hex")}))}},772:(t,e,r)=>{"use strict";var n=r(287).Buffer;Object.defineProperty(e,"__esModule",{value:!0}),e.ShelleyWalletAddress=e.ShelleyWallet=e.Ed25519Key=void 0;const o=r(459),i=r(343),s=r(493);class a{constructor(t,e,r){this.private=t,this.public=e,this.pkh=r}static async generate(){const t=o.ed25519.utils.randomPrivateKey();return await a.fromPrivateKey(t)}static async fromPrivateKey(t){const e=o.ed25519.getPublicKey(t),r=s.blake2b(e,void 0,28);return new a(t,e,r)}static async fromPrivateKeyHex(t){return await a.fromPrivateKey(Uint8Array.from(n.from(t,"hex")))}bech32Pkh(t="stake"){return i.bech32.encode(t,i.bech32.toWords(this.pkh))}bech32PublicKey(t="vk_"){return i.bech32.encode(t,i.bech32.toWords(this.public))}bech32PrivateKey(t="sk_"){return i.bech32.encode(t,i.bech32.toWords(this.private))}async signRaw(t){return o.ed25519.sign(t,this.private)}async verify(t,e){return o.ed25519.verify(e,t,this.public)}json(){return{private:n.from(this.private).toString("hex"),public:n.from(this.public).toString("hex"),pkh:n.from(this.pkh).toString("hex")}}static fromJson(t){if(!t||"object"!=typeof t)throw new Error("Invalid JSON format for Ed25519Key: Input must be a non-null object.");if(!t.private||!t.public||!t.pkh)throw new Error("Invalid JSON format for Ed25519Key: Missing required fields (private, public, or pkh).");return new a(Uint8Array.from(n.from(t.private,"hex")),Uint8Array.from(n.from(t.public,"hex")),Uint8Array.from(n.from(t.pkh,"hex")))}}e.Ed25519Key=a;class f{constructor(t,e){this.paymentKey=t,this.stakeKey=e}static async generate(){return new f(await a.generate(),await a.generate())}addressBech32(t){const e=0==t?"addr_test":"addr";return i.bech32.encode(e,i.bech32.toWords(n.from(this.addressRawBytes(t))),200)}addressRawBytes(t){const e=new Uint8Array(57);return e[0]=t,e.set(this.paymentKey.pkh,1),e.set(this.stakeKey.pkh,29),e}rewardAddressRawBytes(t){const e=224|t,r=new Uint8Array(29);return r[0]=e,r.set(this.stakeKey.pkh,1),r}rewardAddressBech32(t){const e=0==t?"stake_test":"stake";return i.bech32.encode(e,i.bech32.toWords(n.from(this.rewardAddressRawBytes(t))),200)}json(){return{payment:this.paymentKey.json(),stake:this.stakeKey.json()}}static fromJson(t){if(!t||"object"!=typeof t)throw new Error("ShelleyWallet.fromJson: The input must be an object.");const e=t.payment,r=t.stake;if(!e||"object"!=typeof e)throw new Error("ShelleyWallet.fromJson : Invalid payment key: It must be an object.");if(!r||"object"!=typeof r)throw new Error("ShelleyWallet.fromJson : Invalid stake key: It must be an object.");return new f(a.fromJson(e),a.fromJson(r))}static dummy(){return f.fromJson({payment:{pkh:"595ac9bbf256bae584f56a4b671baa4b14a18c8098b8e571834bc12c",private:"5a1380cd79ecaee48d66c14f7d92ddfc866490a3b59d44520e60f16309c8a17d",public:"8d2f4d49118eb1156048b66dd6372cdb1f82da0f8e208d9f8ea4b388c79c09ad"},stake:{pkh:"6706efab75778c2f08b9a5321ead8bfc982a5c08b51a0b2a713cac52",private:"24e8c012c7bef2f5823baef1c06dac253da860a43f0d1f43fc3c8349a4f719a1",public:"f7a1eaea2691ee80b6c0d6f27482145d7037055829b1b26224a5d8f0c2243f16"}})}}e.ShelleyWallet=f;class u{constructor(t,e,r){this.network="mainnet"==t?1:"testnet"==t?0:t,this.paymentKeyHash=e,this.stakeKeyHash=r}static fromRawBytes(t){let e;if(114==t.length&&"string"==typeof t)e=n.from(t,"hex");else{if(57!==t.length)throw Error("ShelleyAddress.fromRawBytes: Invalid byte array length. expected: 57 got: "+t.length);e=n.from(t)}let r=e.subarray(1,29),o=e.subarray(29,57);return new u(e.at(0),r,o)}toBech32(){const t=0==this.network?"addr_test":"addr";return i.bech32.encode(t,i.bech32.toWords(n.from(this.toRawBytes())),200)}toRawBytes(){const t=new Uint8Array(57);return t[0]=this.network,t.set(this.paymentKeyHash,1),t.set(this.stakeKeyHash,29),t}toRawBytesHex(){return n.from(this.toRawBytes()).toString("hex")}}e.ShelleyWalletAddress=u},353:(t,e,r)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0});const n=r(92),o={apiUrl:window.cardanoTestWallet.kuberApiUrl,apiKey:window.cardanoTestWallet.kuberApiKey},i={submitTransaction:t=>(0,n.default)(o.apiUrl+"/api/v1/tx/submit",{method:"POST",headers:{"Content-Type":"application/json","api-key":o.apiKey},body:JSON.stringify({tx:{description:"",type:"Tx ConwayEra",cborHex:t}}),redirect:"follow"}),queryUtxos:t=>async function(t,e="GET",r,i="application/json"){const s=o.apiUrl+t,a={"api-key":o.apiKey};i&&(a["content-type"]=i);const f={method:e,headers:a};return"POST"===e&&r&&(f.body=r),(0,n.default)(s,f).then((async t=>200===t.status?t.json():t.text().then((e=>{let r,n;try{n=JSON.parse(e),r=n?Error(`KuberApi [Status ${t.status}] : ${n.message?n.message:e}`):Error(`KuberApi [Status ${t.status}] : ${e}`)}catch(n){r=Error(`KuberApi [Status ${t.status}] : ${e}`)}throw r.status=t.status,r}))))}("/api/v3/utxo?address="+t)};e.default=i},329:(t,e,r)=>{"use strict";r.r(e),r.d(e,{ALWAYS:()=>Vt,DECIMAL_FIT:()=>$t,DECIMAL_ROUND:()=>qt,Decoder:()=>k,Encoder:()=>It,FLOAT32_OPTIONS:()=>at,NEVER:()=>Dt,REUSE_BUFFER_MODE:()=>Kt,Tag:()=>q,addExtension:()=>jt,clearSource:()=>rt,decode:()=>it,decodeIter:()=>Jt,decodeMultiple:()=>st,encode:()=>Pt,encodeAsAsyncIterable:()=>Ht,encodeAsIterable:()=>Ft,encodeIter:()=>Zt,isNativeAccelerationEnabled:()=>N,roundFloat32:()=>ft});var n=r(287).Buffer;let o,i,s;try{o=new TextDecoder}catch(t){}let a=0;const f=[],u=57342,c=57343,l=57337,h={};let d,p,y,g,b,w,m,E=f,B=0,x={},v=0,A=0,I=[],S=[],U={useRecords:!1,mapsAsObjects:!0},O=!1,T=2;try{new Function("")}catch(t){T=1/0}class k{constructor(t){if(t&&(!t.keyMap&&!t._keyMap||t.useRecords||(t.useRecords=!1,t.mapsAsObjects=!0),!1===t.useRecords&&void 0===t.mapsAsObjects&&(t.mapsAsObjects=!0),t.getStructures&&(t.getShared=t.getStructures),t.getShared&&!t.structures&&((t.structures=[]).uninitialized=!0),t.keyMap)){this.mapKey=new Map;for(let[e,r]of Object.entries(t.keyMap))this.mapKey.set(r,e)}Object.assign(this,t)}decodeKey(t){return this.keyMap&&this.mapKey.get(t)||t}encodeKey(t){return this.keyMap&&this.keyMap.hasOwnProperty(t)?this.keyMap[t]:t}encodeKeys(t){if(!this._keyMap)return t;let e=new Map;for(let[r,n]of Object.entries(t))e.set(this._keyMap.hasOwnProperty(r)?this._keyMap[r]:r,n);return e}decodeKeys(t){if(!this._keyMap||"Map"!=t.constructor.name)return t;if(!this._mapKey){this._mapKey=new Map;for(let[t,e]of Object.entries(this._keyMap))this._mapKey.set(e,t)}let e={};return t.forEach(((t,r)=>e[C(this._mapKey.has(r)?this._mapKey.get(r):r)]=t)),e}mapDecode(t,e){let r=this.decode(t);return this._keyMap&&"Array"===r.constructor.name?r.map((t=>this.decodeKeys(t))):r}decode(t,e){if(i)return et((()=>(rt(),this?this.decode(t,e):k.prototype.decode.call(U,t,e))));s=e>-1?e:t.length,a=0,B=0,A=0,p=null,E=f,y=null,i=t;try{w=t.dataView||(t.dataView=new DataView(t.buffer,t.byteOffset,t.byteLength))}catch(e){if(i=null,t instanceof Uint8Array)throw e;throw new Error("Source must be a Uint8Array or Buffer but was a "+(t&&"object"==typeof t?t.constructor.name:typeof t))}if(this instanceof k){if(x=this,b=this.sharedValues&&(this.pack?new Array(this.maxPrivatePackedValues||16).concat(this.sharedValues):this.sharedValues),this.structures)return d=this.structures,L();(!d||d.length>0)&&(d=[])}else x=U,(!d||d.length>0)&&(d=[]),b=null;return L()}decodeMultiple(t,e){let r,n=0;try{let o=t.length;O=!0;let i=this?this.decode(t,o):ot.decode(t,o);if(!e){for(r=[i];a=y.postBundlePosition){let t=new Error("Unexpected bundle position");throw t.incomplete=!0,t}a=y.postBundlePosition,y=null}if(a==s)d=null,i=null,g&&(g=null);else{if(a>s){let t=new Error("Unexpected end of CBOR data");throw t.incomplete=!0,t}if(!O)throw new Error("Data read, but end of buffer not reached")}return t}catch(t){throw rt(),(t instanceof RangeError||t.message.startsWith("Unexpected end of buffer"))&&(t.incomplete=!0),t}}function R(){let t=i[a++],e=t>>5;if(t&=31,t>23)switch(t){case 24:t=i[a++];break;case 25:if(7==e)return function(){let t=i[a++],e=i[a++],r=(127&t)>>2;if(31===r)return e||3&t?NaN:128&t?-1/0:1/0;if(0===r){let r=((3&t)<<8|e)/(1<<24);return 128&t?-r:r}return V[3]=128&t|56+(r>>1),V[2]=(7&t)<<5|e>>3,V[1]=e<<5,V[0]=0,D[0]}();t=w.getUint16(a),a+=2;break;case 26:if(7==e){let t=w.getFloat32(a);if(x.useFloat32>2){let e=nt[(127&i[a])<<1|i[a+1]>>7];return a+=4,(e*t+(t>0?.5:-.5)>>0)/e}return a+=4,t}t=w.getUint32(a),a+=4;break;case 27:if(7==e){let t=w.getFloat64(a);return a+=8,t}if(e>1){if(w.getUint32(a)>0)throw new Error("JavaScript does not support arrays, maps, or strings with length over 4294967295");t=w.getUint32(a+4)}else x.int64AsNumber?(t=4294967296*w.getUint32(a),t+=w.getUint32(a+4)):t=w.getBigUint64(a);a+=8;break;case 31:switch(e){case 2:case 3:throw new Error("Indefinite length not supported for byte or text strings");case 4:let t,r=[],o=0;for(;(t=R())!=h;)r[o++]=t;return 4==e?r:3==e?r.join(""):n.concat(r);case 5:let i;if(x.mapsAsObjects){let t={};if(x.keyMap)for(;(i=R())!=h;)t[C(x.decodeKey(i))]=R();else for(;(i=R())!=h;)t[C(i)]=R();return t}{m&&(x.mapsAsObjects=!0,m=!1);let t=new Map;if(x.keyMap)for(;(i=R())!=h;)t.set(x.decodeKey(i),R());else for(;(i=R())!=h;)t.set(i,R());return t}case 7:return h;default:throw new Error("Invalid major type for indefinite length "+e)}default:throw new Error("Unknown token "+t)}switch(e){case 0:return t;case 1:return~t;case 2:return r=t,x.copyBuffers?Uint8Array.prototype.slice.call(i,a,a+=r):i.subarray(a,a+=r);case 3:if(A>=a)return p.slice(a-v,(a+=t)-v);if(0==A&&s<140&&t<32){let e=t<16?H(t):function(t){let e=a,r=new Array(t);for(let n=0;n0)return void(a=e);r[n]=t}return F.apply(String,r)}(t);if(null!=e)return e}return j(t);case 4:let e=new Array(t);for(let r=0;r=l){let e=d[8191&t];if(e)return e.read||(e.read=M(e)),e.read();if(t<65536){if(t==c){let t=Q(),e=R(),r=R();$(e,r);let n={};if(x.keyMap)for(let e=2;e23)switch(t){case 24:t=i[a++];break;case 25:t=w.getUint16(a),a+=2;break;case 26:t=w.getUint32(a),a+=4;break;default:throw new Error("Expected array header, but got "+i[a-1])}let e=this.compiledReader;for(;e;){if(e.propertyCount===t)return e(R);e=e.next}if(this.slowReads++>=T){let r=this.length==t?this:this.slice(0,t);return e=x.keyMap?new Function("r","return {"+r.map((t=>x.decodeKey(t))).map((t=>_.test(t)?C(t)+":r()":"["+JSON.stringify(t)+"]:r()")).join(",")+"}"):new Function("r","return {"+r.map((t=>_.test(t)?C(t)+":r()":"["+JSON.stringify(t)+"]:r()")).join(",")+"}"),this.compiledReader&&(e.next=this.compiledReader),e.propertyCount=t,this.compiledReader=e,e(R)}let r={};if(x.keyMap)for(let e=0;e64&&o)return o.decode(i.subarray(a,a+=t));const r=a+t,n=[];for(e="";a65535&&(e-=65536,n.push(e>>>10&1023|55296),e=56320|1023&e),n.push(e)}else n.push(t);n.length>=4096&&(e+=F.apply(String,n),n.length=0)}return n.length>0&&(e+=F.apply(String,n)),e}let F=String.fromCharCode;function H(t){if(t<4){if(t<2){if(0===t)return"";{let t=i[a++];return(128&t)>1?void(a-=1):F(t)}}{let e=i[a++],r=i[a++];if((128&e)>0||(128&r)>0)return void(a-=2);if(t<3)return F(e,r);let n=i[a++];return(128&n)>0?void(a-=3):F(e,r,n)}}{let e=i[a++],r=i[a++],n=i[a++],o=i[a++];if((128&e)>0||(128&r)>0||(128&n)>0||(128&o)>0)return void(a-=4);if(t<6){if(4===t)return F(e,r,n,o);{let t=i[a++];return(128&t)>0?void(a-=5):F(e,r,n,o,t)}}if(t<8){let s=i[a++],f=i[a++];if((128&s)>0||(128&f)>0)return void(a-=6);if(t<7)return F(e,r,n,o,s,f);let u=i[a++];return(128&u)>0?void(a-=7):F(e,r,n,o,s,f,u)}{let s=i[a++],f=i[a++],u=i[a++],c=i[a++];if((128&s)>0||(128&f)>0||(128&u)>0||(128&c)>0)return void(a-=8);if(t<10){if(8===t)return F(e,r,n,o,s,f,u,c);{let t=i[a++];return(128&t)>0?void(a-=9):F(e,r,n,o,s,f,u,c,t)}}if(t<12){let l=i[a++],h=i[a++];if((128&l)>0||(128&h)>0)return void(a-=10);if(t<11)return F(e,r,n,o,s,f,u,c,l,h);let d=i[a++];return(128&d)>0?void(a-=11):F(e,r,n,o,s,f,u,c,l,h,d)}{let l=i[a++],h=i[a++],d=i[a++],p=i[a++];if((128&l)>0||(128&h)>0||(128&d)>0||(128&p)>0)return void(a-=12);if(t<14){if(12===t)return F(e,r,n,o,s,f,u,c,l,h,d,p);{let t=i[a++];return(128&t)>0?void(a-=13):F(e,r,n,o,s,f,u,c,l,h,d,p,t)}}{let y=i[a++],g=i[a++];if((128&y)>0||(128&g)>0)return void(a-=14);if(t<15)return F(e,r,n,o,s,f,u,c,l,h,d,p,y,g);let b=i[a++];return(128&b)>0?void(a-=15):F(e,r,n,o,s,f,u,c,l,h,d,p,y,g,b)}}}}}let D=new Float32Array(1),V=new Uint8Array(D.buffer,0,4);new Array(4096);class q{constructor(t,e){this.value=t,this.tag=e}}I[0]=t=>new Date(t),I[1]=t=>new Date(Math.round(1e3*t)),I[2]=t=>{let e=BigInt(0);for(let r=0,n=t.byteLength;rBigInt(-1)-I[2](t),I[4]=t=>+(t[1]+"e"+t[0]),I[5]=t=>t[1]*Math.exp(t[0]*Math.log(2));const $=(t,e)=>{let r=d[t-=57344];r&&r.isShared&&((d.restoreStructures||(d.restoreStructures=[]))[t]=r),d[t]=e,e.read=M(e)};I[105]=t=>{let e=t.length,r=t[1];$(t[0],r);let n={};for(let o=2;oy?y[0].slice(y.position0,y.position0+=t):new q(t,14),I[15]=t=>y?y[1].slice(y.position1,y.position1+=t):new q(t,15);let K={Error,RegExp};I[27]=t=>(K[t[0]]||Error)(t[1],t[2]);const W=t=>{if(132!=i[a++]){let t=new Error("Packed values structure must be followed by a 4 element array");throw i.length{if(!b){if(!x.getShared)return new q(t,6);tt()}if("number"==typeof t)return b[16+(t>=0?2*t:-2*t-1)];let e=new Error("No support for non-integer packed references yet");throw void 0===t&&(e.incomplete=!0),e},I[28]=t=>{g||(g=new Map,g.id=0);let e,r=g.id++;e=i[a]>>5==4?[]:{};let n={target:e};g.set(r,n);let o=t();return n.used?Object.assign(e,o):(n.target=o,o)},I[28].handlesRead=!0,I[29]=t=>{let e=g.get(t);return e.used=!0,e.target},I[258]=t=>new Set(t),(I[259]=t=>(x.mapsAsObjects&&(x.mapsAsObjects=!1,m=!0),t())).handlesRead=!0,S.push(((t,e)=>t>=225&&t<=255?z(G().prefixes[t-224],e):t>=28704&&t<=32767?z(G().prefixes[t-28672],e):t>=1879052288&&t<=2147483647?z(G().prefixes[t-1879048192],e):t>=216&&t<=223?z(e,G().suffixes[t-216]):t>=27647&&t<=28671?z(e,G().suffixes[t-27639]):t>=1811940352&&t<=1879048191?z(e,G().suffixes[t-1811939328]):1399353956==t?{packedValues:b,structures:d.slice(0),version:e}:55799==t?e:void 0));const Z=1==new Uint8Array(new Uint16Array([1]).buffer)[0],J=[Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array,"undefined"==typeof BigUint64Array?{name:"BigUint64Array"}:BigUint64Array,Int8Array,Int16Array,Int32Array,"undefined"==typeof BigInt64Array?{name:"BigInt64Array"}:BigInt64Array,Float32Array,Float64Array],Y=[64,68,69,70,71,72,77,78,79,85,86];for(let t=0;t{if(!t)throw new Error("Could not find typed array for code "+e);return x.copyBuffers||1!==r&&(2!==r||1&n.byteOffset)&&(4!==r||3&n.byteOffset)&&(8!==r||7&n.byteOffset)?new t(Uint8Array.prototype.slice.call(n,0).buffer):new t(n.buffer,n.byteOffset,n.byteLength)}:r=>{if(!t)throw new Error("Could not find typed array for code "+e);let s=new DataView(r.buffer,r.byteOffset,r.byteLength),a=r.length>>i,f=new t(a),u=s[n];for(let t=0;t23)switch(t){case 24:t=i[a++];break;case 25:t=w.getUint16(a),a+=2;break;case 26:t=w.getUint32(a),a+=4}return t}function tt(){if(x.getShared){let t=et((()=>(i=null,x.getShared())))||{},e=t.structures||[];x.sharedVersion=t.version,b=x.sharedValues=t.packedValues,!0===d?x.structures=d=e:d.splice.apply(d,[0,e.length].concat(e))}}function et(t){let e=s,r=a,n=B,o=v,f=A,u=p,c=E,l=g,h=y,b=new Uint8Array(i.slice(0,s)),m=d,I=x,S=O,U=t();return s=e,a=r,B=n,v=o,A=f,p=u,E=c,g=l,y=h,i=b,O=S,d=m,x=I,w=new DataView(i.buffer,i.byteOffset,i.byteLength),U}function rt(){i=null,g=null,d=null}const nt=new Array(147);for(let t=0;t<256;t++)nt[t]=+("1e"+Math.floor(45.15-.30103*t));let ot=new k({useRecords:!1});const it=ot.decode,st=ot.decodeMultiple,at={NEVER:0,ALWAYS:1,DECIMAL_ROUND:3,DECIMAL_FIT:4};function ft(t){D[0]=t;let e=nt[(127&V[3])<<1|V[2]>>7];return(e*t+(t>0?.5:-.5)>>0)/e}let ut,ct,lt;try{ut=new TextEncoder}catch(t){}const ht="object"==typeof globalThis&&globalThis.Buffer,dt=void 0!==ht,pt=dt?ht.allocUnsafeSlow:Uint8Array,yt=dt?ht:Uint8Array,gt=dt?4294967296:2144337920;let bt,wt,mt,Et,Bt=0,xt=null;const vt=/[\u0080-\uFFFF]/,At=Symbol("record-id");class It extends k{constructor(t){let e,r,n,o,i;super(t),this.offset=0,t=t||{};let s=yt.prototype.utf8Write?function(t,e,r){return wt.utf8Write(t,e,r)}:!(!ut||!ut.encodeInto)&&function(t,e){return ut.encodeInto(t,wt.subarray(e)).written},a=this,f=t.structures||t.saveStructures,u=t.maxSharedStructures;if(null==u&&(u=f?128:0),u>8190)throw new Error("Maximum maxSharedStructure is 8190");let c=t.sequential;c&&(u=0),this.structures||(this.structures=[]),this.saveStructures&&(this.saveShared=this.saveStructures);let l,h,d,p=t.sharedValues;if(p){d=Object.create(null);for(let t=0,e=p.length;tthis.encodeKeys(t)))),this.encode(t,e)},this.encode=function(s,f){if(wt||(wt=new pt(8192),mt=new DataView(wt.buffer,0,8192),Bt=0),Et=wt.length-10,Et-Bt<2048?(wt=new pt(wt.length),mt=new DataView(wt.buffer,0,wt.length),Et=wt.length-10,Bt=0):f===Kt&&(Bt=Bt+7&2147483640),e=Bt,a.useSelfDescribedHeader&&(mt.setUint32(Bt,3654940416),Bt+=3),i=a.structuredClone?new Map:null,a.bundleStrings&&"string"!=typeof s?(xt=[],xt.size=1/0):xt=null,r=a.structures,r){if(r.uninitialized){let t=a.getShared()||{};a.structures=r=t.structures||[],a.sharedVersion=t.version;let e=a.sharedValues=t.packedValues;if(e){d={};for(let t=0,r=e.length;tu&&!c&&(t=u),!r.transitions){r.transitions=Object.create(null);for(let e=0;e0){wt[Bt++]=216,wt[Bt++]=51,Ot(4);let t=e.values;w(t),Ot(0),Ot(0),h=Object.create(d||null);for(let e=0,r=t.length;eEt&&E(Bt),a.offset=Bt;let t=function(t,e){let r,n=2*e.length,o=t.length-n;e.sort(((t,e)=>t.offset>e.offset?1:-1));for(let r=0;r>8,t[e]=255&r}for(;r=e.pop();){let e=r.offset;t.copyWithin(e+n,e,o),n-=2;let i=e+n;t[i++]=216,t[i++]=28,o=e}return t}(wt.subarray(e,Bt),i.idsToInsert);return i=null,t}return f&Kt?(wt.start=e,wt.end=Bt,wt):wt.subarray(e,Bt)}finally{if(r)if(b<10&&b++,r.length>u&&(r.length=u),g>1e4)r.transitions=null,b=0,g=0,y.length>0&&(y=[]);else if(y.length>0&&!c){for(let t=0,e=y.length;tu&&(a.structures=a.structures.slice(0,u));let t=wt.subarray(e,Bt);return!1===a.updateSharedData()?a.encode(s):t}f&Wt&&(Bt=e)}},this.findCommonStringsToPack=()=>(l=new Map,d||(d=Object.create(null)),t=>{let e=t&&t.threshold||4,r=this.pack?t.maxPrivatePackedValues||16:0;p||(p=this.sharedValues=[]);for(let[t,o]of l)o.count>e&&(d[t]=r++,p.push(t),n=!0);for(;this.saveShared&&!1===this.updateSharedData(););l=null});const w=r=>{Bt>Et&&(wt=E(Bt));var n,o=typeof r;if("string"===o){if(h){let e=h[r];if(e>=0)return void(e<16?wt[Bt++]=e+224:(wt[Bt++]=198,w(1&e?15-e>>1:e-16>>1)));if(l&&!t.pack){let t=l.get(r);t?t.count++:l.set(r,{count:1})}}let o,i=r.length;if(xt&&i>=4&&i<1024){if((xt.size+=i)>61440){let t,r=(xt[0]?3*xt[0].length+xt[1].length:0)+10;Bt+r>Et&&(wt=E(Bt+r)),wt[Bt++]=217,wt[Bt++]=223,wt[Bt++]=249,wt[Bt++]=xt.position?132:130,wt[Bt++]=26,t=Bt-e,Bt+=4,xt.position&&Ct(e,w),xt=["",""],xt.size=0,xt.position=t}let t=vt.test(r);return xt[t?0:1]+=r,wt[Bt++]=t?206:207,void w(i)}o=i<32?1:i<256?2:i<65536?3:5;let a=3*i;if(Bt+a>Et&&(wt=E(Bt+a)),i<64||!s){let t,e,s,a=Bt+o;for(t=0;t>6|192,wt[a++]=63&e|128):55296==(64512&e)&&56320==(64512&(s=r.charCodeAt(t+1)))?(e=65536+((1023&e)<<10)+(1023&s),t++,wt[a++]=e>>18|240,wt[a++]=e>>12&63|128,wt[a++]=e>>6&63|128,wt[a++]=63&e|128):(wt[a++]=e>>12|224,wt[a++]=e>>6&63|128,wt[a++]=63&e|128);n=a-Bt-o}else n=s(r,Bt+o,a);n<24?wt[Bt++]=96|n:n<256?(o<2&&wt.copyWithin(Bt+2,Bt+1,Bt+1+n),wt[Bt++]=120,wt[Bt++]=n):n<65536?(o<3&&wt.copyWithin(Bt+3,Bt+2,Bt+2+n),wt[Bt++]=121,wt[Bt++]=n>>8,wt[Bt++]=255&n):(o<5&&wt.copyWithin(Bt+5,Bt+3,Bt+3+n),wt[Bt++]=122,mt.setUint32(Bt,n),Bt+=4),Bt+=n}else if("number"===o)if(this.alwaysUseFloat||r>>>0!==r)if(this.alwaysUseFloat||r>>0!==r){let t;if((t=this.useFloat32)>0&&r<4294967296&&r>=-2147483648){let e;if(wt[Bt++]=250,mt.setFloat32(Bt,r),t<4||(e=r*nt[(127&wt[Bt])<<1|wt[Bt+1]>>7])>>0===e)return void(Bt+=4);Bt--}wt[Bt++]=251,mt.setFloat64(Bt,r),Bt+=8}else r>=-24?wt[Bt++]=31-r:r>=-256?(wt[Bt++]=56,wt[Bt++]=~r):r>=-65536?(wt[Bt++]=57,mt.setUint16(Bt,~r),Bt+=2):(wt[Bt++]=58,mt.setUint32(Bt,~r),Bt+=4);else r<24?wt[Bt++]=r:r<256?(wt[Bt++]=24,wt[Bt++]=r):r<65536?(wt[Bt++]=25,wt[Bt++]=r>>8,wt[Bt++]=255&r):(wt[Bt++]=26,mt.setUint32(Bt,r),Bt+=4);else if("object"===o)if(r){if(i){let t=i.get(r);if(t){if(wt[Bt++]=216,wt[Bt++]=29,wt[Bt++]=25,!t.references){let e=i.idsToInsert||(i.idsToInsert=[]);t.references=[],e.push(t)}return t.references.push(Bt-e),void(Bt+=2)}i.set(r,{offset:Bt-e})}let t=r.constructor;if(t===Object)m(r,!0);else if(t===Array){(n=r.length)<24?wt[Bt++]=128|n:Ot(n);for(let t=0;t>8,wt[Bt++]=255&n):(wt[Bt++]=186,mt.setUint32(Bt,n),Bt+=4),a.keyMap)for(let[t,e]of r)w(a.encodeKey(t)),w(e);else for(let[t,e]of r)w(t),w(e);else{for(let t=0,e=ct.length;t>8,wt[Bt++]=255&n):n>-1&&(wt[Bt++]=218,mt.setUint32(Bt,n),Bt+=4),void e.encode.call(this,r,w,E)}if(r[Symbol.iterator]){if(bt){let t=new Error("Iterable should be serialized as iterator");throw t.iteratorNotHandled=!0,t}wt[Bt++]=159;for(let t of r)w(t);return void(wt[Bt++]=255)}if(r[Symbol.asyncIterator]||kt(r)){let t=new Error("Iterable/blob should be serialized as iterator");throw t.iteratorNotHandled=!0,t}if(this.useToJSON&&r.toJSON){const t=r.toJSON();if(t!==r)return w(t)}m(r,!r.hasOwnProperty)}}else wt[Bt++]=246;else if("boolean"===o)wt[Bt++]=r?245:244;else if("bigint"===o){if(r=0)wt[Bt++]=27,mt.setBigUint64(Bt,r);else if(r>-(BigInt(1)<{let e=Object.keys(t),r=Object.values(t),n=e.length;if(n<24?wt[Bt++]=160|n:n<256?(wt[Bt++]=184,wt[Bt++]=n):n<65536?(wt[Bt++]=185,wt[Bt++]=n>>8,wt[Bt++]=255&n):(wt[Bt++]=186,mt.setUint32(Bt,n),Bt+=4),a.keyMap)for(let t=0;t{wt[Bt++]=185;let n=Bt-e;Bt+=2;let o=0;if(a.keyMap)for(let e in t)(r||t.hasOwnProperty(e))&&(w(a.encodeKey(e)),w(t[e]),o++);else for(let e in t)(r||t.hasOwnProperty(e))&&(w(e),w(t[e]),o++);wt[n+++e]=o>>8,wt[n+e]=255&o}:(t,e)=>{let r,i,s,a=o.transitions||(o.transitions=Object.create(null)),f=0,c=0;if(this.keyMap){s=Object.keys(t).map((t=>this.encodeKey(t))),c=s.length;for(let t=0;t>8|224,wt[Bt++]=255&l;else{if(s||(s=a.__keys__||(a.__keys__=Object.keys(t))),void 0===i?(l=o.nextId++,l||(l=0,o.nextId=1),l>=256&&(o.nextId=(l=u)+1)):l=i,o[l]=s,!(l=256-u&&(y.shift()[At]=void 0),y.push(a),Ot(c+2),w(57344+l),w(s),null===e)return;for(let r in t)(e||t.hasOwnProperty(r))&&w(t[r]);return}wt[Bt++]=217,wt[Bt++]=l>>8|224,wt[Bt++]=255&l,a=o.transitions;for(let t=0;t{let r;if(t>16777216){if(t-e>gt)throw new Error("Encoded buffer would be larger than maximum buffer size");r=Math.min(gt,4096*Math.round(Math.max((t-e)*(t>67108864?1.25:2),4194304)/4096))}else r=1+(Math.max(t-e<<2,wt.length-1)>>12)<<12;let n=new pt(r);return mt=new DataView(n.buffer,0,r),wt.copy?wt.copy(n,0,e,t):n.set(wt.slice(e,t)),Bt-=e,e=0,Et=n.length-10,wt=n};let B=100,x=1e3;function*v(t,r,n){let o=t.constructor;if(o===Object){let e=!1!==a.useRecords;e?m(t,null):St(Object.keys(t).length,160);for(let n in t){let o=t[n];e||w(n),o&&"object"==typeof o?r[n]?yield*v(o,r[n]):yield*A(o,r,n):w(o)}}else if(o===Array){let n=t.length;Ot(n);for(let o=0;oB)?r.element?yield*v(n,r.element):yield*A(n,r,"element"):w(n)}}else if(t[Symbol.iterator]){wt[Bt++]=159;for(let n of t)n&&("object"==typeof n||Bt-e>B)?r.element?yield*v(n,r.element):yield*A(n,r,"element"):w(n);wt[Bt++]=255}else kt(t)?(St(t.size,64),yield wt.subarray(e,Bt),yield t,I()):t[Symbol.asyncIterator]?(wt[Bt++]=159,yield wt.subarray(e,Bt),yield t,I(),wt[Bt++]=255):w(t);n&&Bt>e?yield wt.subarray(e,Bt):Bt-e>B&&(yield wt.subarray(e,Bt),I())}function*A(t,r,n){let o=Bt-e;try{w(t),Bt-e>B&&(yield wt.subarray(e,Bt),I())}catch(i){if(!i.iteratorNotHandled)throw i;r[n]={},Bt=e+o,yield*v.call(this,t,r[n])}}function I(){B=x,a.encode(null,zt)}function S(t,e,r){return B=e&&e.chunkThreshold?x=e.chunkThreshold:100,t&&"object"==typeof t?(a.encode(null,zt),r(t,a.iterateProperties||(a.iterateProperties={}),!0)):[a.encode(t)]}async function*U(t,e){for(let r of v(t,e,!0)){let t=r.constructor;if(t===yt||t===Uint8Array)yield r;else if(kt(r)){let t,e=r.stream().getReader();for(;!(t=await e.read()).done;)yield t.value}else if(r[Symbol.asyncIterator])for await(let t of r)I(),t?yield*U(t,e.async||(e.async={})):yield a.encode(t);else yield r}}this.encodeAsIterable=function(t,e){return S(t,e,v)},this.encodeAsAsyncIterable=function(t,e){return S(t,e,U)}}useBuffer(t){wt=t,mt=new DataView(wt.buffer,wt.byteOffset,wt.byteLength),Bt=0}clearSharedData(){this.structures&&(this.structures=[]),this.sharedValues&&(this.sharedValues=void 0)}updateSharedData(){let t=this.sharedVersion||0;this.sharedVersion=t+1;let e=this.structures.slice(0),r=new Ut(e,this.sharedValues,this.sharedVersion),n=this.saveShared(r,(e=>(e&&e.version||0)==t));return!1===n?(r=this.getShared()||{},this.structures=r.structures||[],this.sharedValues=r.packedValues,this.sharedVersion=r.version,this.structures.nextId=this.structures.length):e.forEach(((t,e)=>this.structures[e]=t)),n}}function St(t,e){t<24?wt[Bt++]=e|t:t<256?(wt[Bt++]=24|e,wt[Bt++]=t):t<65536?(wt[Bt++]=25|e,wt[Bt++]=t>>8,wt[Bt++]=255&t):(wt[Bt++]=26|e,mt.setUint32(Bt,t),Bt+=4)}class Ut{constructor(t,e,r){this.structures=t,this.packedValues=e,this.version=r}}function Ot(t){t<24?wt[Bt++]=128|t:t<256?(wt[Bt++]=152,wt[Bt++]=t):t<65536?(wt[Bt++]=153,wt[Bt++]=t>>8,wt[Bt++]=255&t):(wt[Bt++]=154,mt.setUint32(Bt,t),Bt+=4)}const Tt="undefined"==typeof Blob?function(){}:Blob;function kt(t){if(t instanceof Tt)return!0;let e=t[Symbol.toStringTag];return"Blob"===e||"File"===e}function Lt(t,e){switch(typeof t){case"string":if(t.length>3){if(e.objectMap[t]>-1||e.values.length>=e.maxValues)return;let r=e.get(t);if(r)2==++r.count&&e.values.push(t);else if(e.set(t,{count:1}),e.samplingPackedValues){let r=e.samplingPackedValues.get(t);r?r.count++:e.samplingPackedValues.set(t,{count:1})}}break;case"object":if(t)if(t instanceof Array)for(let r=0,n=t.length;r1&&(t-=4),{tag:t,encode:function(t,e){let r=t.byteLength,n=t.byteOffset||0,o=t.buffer||t;e(dt?ht.from(o,n,r):new Uint8Array(o,n,r))}}}function Mt(t,e){let r=t.byteLength;r<24?wt[Bt++]=64+r:r<256?(wt[Bt++]=88,wt[Bt++]=r):r<65536?(wt[Bt++]=89,wt[Bt++]=r>>8,wt[Bt++]=255&r):(wt[Bt++]=90,mt.setUint32(Bt,r),Bt+=4),Bt+r>=wt.length&&e(Bt+r),wt.set(t.buffer?t:new Uint8Array(t),Bt),Bt+=r}function Ct(t,e){mt.setUint32(xt.position+t,Bt-xt.position-t+1);let r=xt;xt=null,e(r[0]),e(r[1])}function jt(t){if(t.Class){if(!t.encode)throw new Error("Extension has no encode function");lt.unshift(t.Class),ct.unshift(t)}!function(t){I[t.tag]=t.decode}(t)}lt=[Date,Set,Error,RegExp,q,ArrayBuffer,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array,"undefined"==typeof BigUint64Array?function(){}:BigUint64Array,Int8Array,Int16Array,Int32Array,"undefined"==typeof BigInt64Array?function(){}:BigInt64Array,Float32Array,Float64Array,Ut],ct=[{tag:1,encode(t,e){let r=t.getTime()/1e3;(this.useTimestamp32||0===t.getMilliseconds())&&r>=0&&r<4294967296?(wt[Bt++]=26,mt.setUint32(Bt,r),Bt+=4):(wt[Bt++]=251,mt.setFloat64(Bt,r),Bt+=8)}},{tag:258,encode(t,e){e(Array.from(t))}},{tag:27,encode(t,e){e([t.name,t.message])}},{tag:27,encode(t,e){e(["RegExp",t.source,t.flags])}},{getTag:t=>t.tag,encode(t,e){e(t.value)}},{encode(t,e,r){Mt(t,r)}},{getTag(t){if(t.constructor===Uint8Array&&(this.tagUint8Array||dt&&!1!==this.tagUint8Array))return 64},encode(t,e,r){Mt(t,r)}},_t(68,1),_t(69,2),_t(70,4),_t(71,8),_t(72,1),_t(77,2),_t(78,4),_t(79,8),_t(85,4),_t(86,8),{encode(t,e){let r=t.packedValues||[],n=t.structures||[];if(r.values.length>0){wt[Bt++]=216,wt[Bt++]=51,Ot(4);let t=r.values;e(t),Ot(0),Ot(0),packedObjectMap=Object.create(sharedPackedObjectMap||null);for(let e=0,r=t.length;e{let e;n&&(t=Gt.concat([n,t]),n=void 0);try{e=r.decodeMultiple(t)}catch(r){if(!r.incomplete)throw r;n=t.slice(r.lastPosition),e=r.values}return e};return"function"==typeof t[Symbol.iterator]?function*(){for(const e of t)yield*o(e)}():"function"==typeof t[Symbol.asyncIterator]?async function*(){for await(const e of t)yield*o(e)}():void 0}}},e={};function r(n){var o=e[n];if(void 0!==o)return o.exports;var i=e[n]={exports:{}};return t[n](i,i.exports,r),i.exports}r.d=(t,e)=>{for(var n in e)r.o(e,n)&&!r.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),r.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},(()=>{"use strict";const t=r(374);(async()=>{if(null==window.cardanoTestWallet.walletName)throw new Error('Please specify the wallet name in the cardanoTestWallet.config object. Example: { walletName: "MyWallet" }');const e=await(0,t.mkCardanoWalletExtension)();window.cardano={demos:e}})()})()})(); \ No newline at end of file diff --git a/tests/cardano-test-wallet/index.js.LICENSE.txt b/tests/cardano-test-wallet/index.js.LICENSE.txt deleted file mode 100644 index 945120b77..000000000 --- a/tests/cardano-test-wallet/index.js.LICENSE.txt +++ /dev/null @@ -1,23 +0,0 @@ -/*! - * - * /*! - * * The cardano-test-wallet module for browser environments. - * * - * * @author Nabin Kawan - * * @license MIT - * * / - * - */ - -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ - -/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ - -/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ diff --git a/tests/cardano-test-wallet/types.d.ts b/tests/cardano-test-wallet/types.d.ts deleted file mode 100644 index a08f06b18..000000000 --- a/tests/cardano-test-wallet/types.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -export type HexString = string; -export interface CIP30Provider { - apiVersion: string; - enable: () => Promise; - icon: string; - isEnabled: () => Promise; - name: string; - supportedExtensions: Record[]; -} -export interface CIP30Instance { - submitTx: (tx: string) => Promise; - signTx: (tx: string, partial?: Boolean) => Promise; - getChangeAddress: () => Promise; - getNetworkId: () => Promise; - getRewardAddresses: () => Promise; - getUnusedAddresses: () => Promise; - getUsedAddresses: () => Promise>; - getUtxos: (amount?: object, paginate?: any) => Promise>; - getCollateral?: () => Promise>; - signData: (address: string, payload: HexString) => Promise; - getBalance: () => Promise; -} -export interface Cip95Instance extends CIP30Instance { - cip95: { - getPubDRepKey: () => Promise; - getUnregisteredPubStakeKeys: () => Promise; - getRegisteredPubStakeKeys: () => Promise; - }; - getActivePubStakeKeys: () => Promise; - getExtensions: () => Record[]; -} -export type CardanoTestWallet = { - payment: { - private: string; - public: string; - pkh: string; - }; - stake: { - private: string; - public: string; - pkh: string; - }; -}; -export type CardanoTestWalletConfig = { - networkId?: number; - walletName?: string; - enableStakeSigning?: boolean; - extraRegisteredPubStakeKeys?: string[]; - extraRewardAddresses?: string[]; - kuberApiUrl: string; - kuberApiKey: string; -}; -export type KuberValue = { - [policyId: string]: Record | BigInt | number; -}; diff --git a/tests/govtool-backend/lib/faucet_api.py b/tests/govtool-backend/lib/faucet_api.py index b6c63c9de..68e02ec08 100644 --- a/tests/govtool-backend/lib/faucet_api.py +++ b/tests/govtool-backend/lib/faucet_api.py @@ -25,7 +25,7 @@ def from_env(): api_key = FACUET_API_KEY base_url = FAUCET_API_URL if not api_key: - raise ValueError("FAUCET_API_KEY environment variable not set.") + raise ValueError("FAUCET_API_KEY environment variable not set. Please set this variable or fund missing balance to the wallet address: addr_test1qzc97zml9xzhm7xcsmqretkk7ztzyehj3dpd7ph7h0s40wp0ea9f3e353pmmr7yxv7m2dj09rn44m7pvd0m4cylusn8szlm75t") return CardanoFaucet(api_key, base_url) def send_money(self, address: str, tx_type: str = "default") -> Transaction: diff --git a/tests/govtool-frontend/playwright/.env.example b/tests/govtool-frontend/playwright/.env.example index 33e20db29..d233f6b20 100644 --- a/tests/govtool-frontend/playwright/.env.example +++ b/tests/govtool-frontend/playwright/.env.example @@ -1,14 +1,7 @@ HOST_URL=http://localhost:3000 -API_URL=http://localhost:3000/api DOCS_URL=https://docs.gov.tools - -PDF_URL=https://dev.api.pdf.gov.tools - -# Faucet -FAUCET_API_KEY= - #Blockfrost BLOCKFROST_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXX @@ -21,12 +14,9 @@ TX_TIMEOUT=240000 # milliseconds # Metadata Bucket METADATA_BUCKET_URL=https://metadata-govtool.cardanoapi.io -FAUCET_ADDRESS=addr_test1vqeux7xwusdju9dvsj8h7mca9aup2k439kfmwy773xxc2hcu7zy99 - - -PROPOSAL_FAUCET_PAYMENT_PRIVATE=********************************************** -PROPOSAL_FAUCET_STAKE_PRIVATE=********************************************** -PROPOSAL_FAUCET_DREP_PRIVATE=********************************************** +FAUCET_ADDRESS= +FAUCET_PAYMENT_PRIVATE= +FAUCET_STAKE_PKH= CI=true -TEST_WORKERS=6 \ No newline at end of file +TEST_WORKERS=6 // Number of workers to run in parallel \ No newline at end of file diff --git a/tests/govtool-frontend/playwright/.gitignore b/tests/govtool-frontend/playwright/.gitignore index f8c7b5f89..c066977bb 100644 --- a/tests/govtool-frontend/playwright/.gitignore +++ b/tests/govtool-frontend/playwright/.gitignore @@ -22,4 +22,5 @@ lib/_mock/registeredDRepCopyWallets.json lib/_mock/wallets.json lib/_mock/proposals.json lib/_mock/protocolParameter.json -./lock_logs.txt +lib/_mock/faucetWalletBalance.json +lock_logs.txt diff --git a/tests/govtool-frontend/playwright/DEVELOPERS_GUIDE.md b/tests/govtool-frontend/playwright/DEVELOPERS_GUIDE.md new file mode 100644 index 000000000..5869e5171 --- /dev/null +++ b/tests/govtool-frontend/playwright/DEVELOPERS_GUIDE.md @@ -0,0 +1,202 @@ +# **Developer's Guide** + +This document serves as a guide for new developers participating in the project. It provides an overview of the project’s directory structure and describes the purpose of each component. + +--- + +## **Directory Structure** + +### `lib/` + +Contains the utility logic, helpers, mock datas and shared services, including: + +- \_mock (mock data) +- constants +- datafactory +- fixtures +- forms +- Pages +- helpers +- Services + +--- + +## **Test Directory: `tests/`** + +This directory contains all automated test cases, organized by feature area: + +### Feature-Based Test Suites + +1. **`1-wallet-connect/`** + Wallet connection test cases. + +2. **`2-delegation/`** + Delegation functionality and visibility tests for delegated wallets. + +3. **`3-drep-registration/`** + dRep registration, editing functionality, validation, and visibility test cases. + +4. **`4-proposal-visibility/`** + Voting visibility tests for voting pillars. + +5. **`5-proposal-functionality/`** + Voting functionality tests and validation of voting metadata. + +6. **`6-miscellaneous/`** + Miscellaneous tests, such as documentation URL checks. + +7. **`7-proposal-submission/`** + Proposal submission form validation, visibility, draft handling, and submission tests. + +8. **`8-proposal-discussion/`** + Tests related to proposal discussions adjacent to the submission form. + +9. **`9-outcomes/`** + Tests related to proposal outcome visibility and validations. + +10. **`10-user-snap/`** + Usersnap-related test cases. + +11. **`11-proposal-budget/`** + Tests for proposal budget functionality and associated forms. + +12. **`12-proposal-budget-submission/`** + Proposal budget submission form validation, draft, visibility, and submission tests. + +--- + +### Authentication & Setup Scripts + +13. **`adaholder.auth.setup.ts`** + Sets up authentication for adaHolder wallets. + +14. **`user.auth.setup.ts`** + Sets up authentication for user wallets. + +15. **`proposal-budget.auth.setup.ts`** + Authentication setup for proposal budget wallets. + +16. **`proposal-discussion.auth.setup.ts`** + Authentication setup for proposal discussion wallets. + +17. **`dRep.auth.setup.ts`** + Authentication setup for dRep wallets. + +18. **`dRep.setup.ts`** + Setup for temporary and static dRep wallet registration. + +19. **`proposal-budget.dRep.setup.ts`** + dRep wallet registration setup for proposal budget tests. + +20. **`proposal.setup.ts`** + Setup for proposal submission wallets. + +21. **`wallet.bootstrap.ts`** + Initializes adaHolder and dRep wallets with test funds for spendable ADA functionality. + +--- + +### Teardown Scripts + +21. **`delegation.teardown.ts`** + Resets delegation status (abstains delegation from delegated wallets). + +22. **`faucet.teardown.ts`** + Refunds all unspendable ADA from test wallets back to the faucet wallet. + +23. **`dRep.teardown.ts`** + Handles deregistration of dRep wallets registered during tests or setup. + +24. **`generated-artifacts.teardown.ts`** + Remove all artifacts generated during test execution + +--- + +## 🖥️ Tip for VS Code Users: Running Individual Tests + +- Use the terminal to run specific test suites using the commands provided in the **README.md**. +- Ensure all test files are recognized in the **Test Explorer**. + +![Test Runner Screenshot](./docs/image.png) + +- Use the **Play** ▶️ icon to run individual tests directly from the UI. + +--- + +### 🎯 Running Individual Tests Without Wallet Dependency + +- Add **Playwright Test for VSCode** extension + + ![Playwright Test Screenshot](./docs/image-1.png) + +1. **Remove** the `CI` environment variable. +2. **Navigate** to the specific directory where your test is located to run it directly. + + ![Directory Navigation Screenshot](./docs/image-2.png) + +> **Note:** +> +> - To run tests _without wallet dependency_, make sure the required wallet/auth setup has already been completed beforehand. +> - To run tests _with wallet dependency_ and generate **Allure reports**, **do not** remove the `CI` environment variable. + +--- + +## Govtool Playwright Configuration – Project Behaviors + +This section outlines the core behavioral areas of the Govtool application as captured and tested using Playwright. Visual representations are provided to guide developers in understanding the UI states and interaction flows. + +### 1. Delegation Pillars + +This set of tests covers all key UI and interaction flows related to delegation functionality. + +![Delegation Pillars](./docs/delegation-pillars.png) + +--- + +### 2. Voting Pillars + +Covers user voting mechanisms, including interface states and validation of voting logic. + +![Voting Pillars](./docs/voting-pillars.png) + +--- + +### 3. Proposal Pillars + +Proposal functionality is split into two sub-categories, each with distinct test coverage: + +#### i. Proposal Discussion + +Tracks creation, display, and participation in proposal discussions. + +![Proposal Discussion](./docs/proposal-discussion.png) + +#### ii. Budget Proposal + +Tracks creation, display, and participation in budget-related proposals. + +![Budget Proposal](./docs/budget-proposal.png) + +--- + +### 4. Outcomes Pillars + +Tests centered around outcomes from various actions. + +![Outcomes Pillars](./docs/outcomes-pillars.png) + +--- + +### 5. Logged-In State + +Covers all test cases that require the user to be authenticated, and are not included in the delegation, voting, proposal, or outcomes pillars + +![Logged-In State](./docs/loggedin.png) + +--- + +### Overall Architecture + +For a comprehensive view of the project's Playwright architecture, refer to the Excalidraw diagram: + +[Govtool Project Architecture](./docs/govtool-playwright-project.excalidraw) diff --git a/tests/govtool-frontend/playwright/README.md b/tests/govtool-frontend/playwright/README.md index 47a5edca3..567219012 100644 --- a/tests/govtool-frontend/playwright/README.md +++ b/tests/govtool-frontend/playwright/README.md @@ -1,29 +1,353 @@ -# GitHub Pages Deployment SSH Deploy Key Generation Guide +# 🚀 GovTool Integration Test Guide -This guide walks you through the process of generating an SSH deploy key for GitHub Pages deployment and securely integrating it into your workflow. +## ✅ Prerequisites -## Generating the SSH Deploy Key +Ensure the following tools are installed on your machine: -Execute the following command in your terminal to generate the SSH deploy key: +- **Git** +- **Node.js** & **npm** + +--- + +## 🛠️ Setup Instructions + +### 1. Clone the Repository + +```bash +git clone https://github.com/IntersectMBO/govtool +``` + +### 2. Navigate to the Playwright Test Directory + +```bash +cd govtool/tests/govtool-frontend/playwright +``` + +### 3. Configure Environment Variables + +- Copy the example file: + + ```bash + cp .env.example .env + ``` + +- Update the `.env` file with the appropriate values for your environment. + +### 4. Install Project Dependencies + +```bash +npm install +``` + +### 5. Install Playwright Browsers + +```bash +npx playwright install +``` + +--- + +## 🌐 Environment Setup + +### HOST URL + +| Environment | URL | +| :---------- | :----------------------------------------------------------------------------------------------------------------------- | +| Development | [https://p80-z78acf3c2-zded6a792-gtw.z937eb260.rustrocks.fr](https://p80-z78acf3c2-zded6a792-gtw.z937eb260.rustrocks.fr) | +| QA | [https://govtool.cardanoapi.io](https://govtool.cardanoapi.io) | +| Preview | [https://preview.gov.tools](https://preview.gov.tools) | +| Pre-Prod | [https://pre-prod.gov.tools](https://pre-prod.gov.tools) | +| Mainnet | [https://gov.tools](https://gov.tools) | + +--- + +## 🔑 Generate API Keys + +### Blockfrost API Key + +- To generate a Blockfrost API key (Project ID): + 1. Follow the instructions in the [Blockfrost documentation](https://blockfrost.dev/overview/getting-started). + 2. The **Project ID** you create there serves as your **Blockfrost API Key**. + +### Kuber API Key + +- To generate a Kuber API Key: + 1. Visit [Kuberide](https://kuberide.com/). + 2. Log in using your Google or GitHub account. + 3. Navigate to **API Keys**. + 4. Click to **Generate API Key**. + +--- + +## 🔧 Faucet wallet Configuration + +This section guides you through generating a Cardano faucet wallet and configuring it for use. Follow the steps below to create and set the config on env + +### Step 1: Generate a Faucet Wallet + +Run the following command to generate a new faucet wallet: + +```bash +npm run generate-faucet-wallet +``` + +The script will: + +- Display the wallet details (payment private key, stake public key hash, and wallet address) in the terminal. + +**Example Output:** + +``` +🎉 Wallet generated successfully! +----------------------------------- +🔑 Payment Private Key: +🔗 Stake Public Key Hash: +🏠 Wallet Address: +----------------------------------- + +📋 Please copy the following to your environment variables: +1. Set FAUCET_PAYMENT_PRIVATE= +2. Set FAUCET_STAKE_PKH= +3. Set FAUCET_ADDRESS= + +🎈 All set! Please ensure this wallet is funded with a sufficient balance +``` + +### Step 2: Configure Environment Variables + +Securely store the generated wallet details in your environment variables. Add the following to your `.env` file or environment configuration: + +```env +FAUCET_PAYMENT_PRIVATE= +FAUCET_STAKE_PKH= +FAUCET_ADDRESS= +``` + +⚠️ **Security Note**: Store your wallet details in a secure location for future use. The payment private key is sensitive and must be protected to prevent unauthorized access to your funds. + +### Step 3: Fund the Wallet + +Ensure the wallet address has sufficient funds for your test runs. The required balance depends on the specific tests you plan to execute (refer to the test-specific test run details below). + +To check the wallet balance, visit: + +``` +https://${network}.cardanoscan.io/address/ +``` + +Replace `${network}` with the appropriate Cardano network (e.g.`preprod`, or `preview`) and `` with the generated address. + +**Example**: + +- For a preview wallet: `https://preview.cardanoscan.io/address/` +- Monitor the balance to ensure it meets the requirements for individual or all test runs. + +--- + +## 🧪 Running Tests + +### 🔑 Generate Test Wallets + +Before each test run, generate test wallets required for wallet-dependent tests: + +```bash +npm run generate-wallets +``` + +--- + +### 🔁 Run All Tests + +- **Pre-requisite**: Ensure the faucet address holds at least **412,000 ADA**. + +#### 🖥️ UI Mode + +```bash +npm run test +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless +``` + +--- + +### ▶️ Run Specific Test Suites + +Each test suite can be run in **UI** or **Headless** mode. + +--- + +#### 1. **Delegation Pillar** + +- **Pre-requisite**: Ensure the faucet address holds at least **12,000 ADA**. + +#### 🖥️ UI Mode + +```bash +npm run test:delegation-pillar +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:delegation-pillar +``` + +--- + +#### 2. **Voting Pillar** + +- **Pre-requisite**: Ensure the faucet address holds at least **12,000 ADA**. + +#### 🖥️ UI Mode + +```bash +npm run test:voting-pillar +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:voting-pillar +``` + +--- + +#### 3. **Outcomes** + +#### 🖥️ UI Mode + +```bash +npm run test:outcomes +``` + +#### 🧪 Headless Mode (No UI) ```bash -ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N "" +npm run test:headless:outcomes ``` -This command will generate two files: +--- + +#### 4. **Proposal Pillar** + +_Includes both Proposal Discussion and Budget Discussion_ + +- **Pre-requisite**: Ensure the faucet address holds at least **403,000 ADA**. + +#### 🖥️ UI Mode + +```bash +npm run test:proposal-pillar +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:proposal-pillar +``` + +--- + +#### 5. **Proposal Discussion** + +- **Pre-requisite**: Ensure the faucet address holds at least **401,000 ADA**. + +#### 🖥️ UI Mode + +```bash +npm run test:proposal-discussion +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:proposal-discussion +``` -- `gh-pages.pub`: Public key -- `gh-pages`: Private key +--- -## Integration Steps +#### 6. **Proposal Budget** -1. **Repository Settings:** +- **Pre-requisite**: Ensure the faucet address holds at least **1,000 ADA**. + +#### 🖥️ UI Mode + +```bash +npm run test:proposal-budget +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:proposal-budget +``` + +--- + +#### 7. **Wallet Connect** + +#### 🖥️ UI Mode + +```bash +npm run test:wallet-connect +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:wallet-connect +``` + +--- + +#### 8. **Usersnap Integration** + +#### 🖥️ UI Mode + +```bash +npm run test:usersnap +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:usersnap +``` + +--- + +#### 9. **Miscellaneous Tests** + +#### 🖥️ UI Mode + +```bash +npm run test:misc +``` + +#### 🧪 Headless Mode (No UI) + +```bash +npm run test:headless:misc +``` + +--- + +## 📊 Visualize Allure Report + +To generate and view an Allure test report: + +```bash +npm run allure:serve +``` - - Navigate to your repository settings. +--- -2. **Adding Public Key to Deploy Keys: Add to** [`https://github.com/cardanoapi/govtool-test-reports`](https://github.com/cardanoapi/govtool-test-reports) +## 📚 Additional Resources - - Go to Deploy Keys and add your public key. Make sure to grant it write access. +For contribution guidelines and development tips, refer to: -3. **Adding Private Key to Secrets:** - - Go to Secrets and add your private key as `DEPLOY_KEY`. +📄 **[DEVELOPERS_GUIDE.md](./DEVELOPERS_GUIDE.md)** diff --git a/tests/govtool-frontend/playwright/docs/budget-proposal.png b/tests/govtool-frontend/playwright/docs/budget-proposal.png new file mode 100644 index 000000000..c77327ef9 Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/budget-proposal.png differ diff --git a/tests/govtool-frontend/playwright/docs/delegation-pillars.png b/tests/govtool-frontend/playwright/docs/delegation-pillars.png new file mode 100644 index 000000000..9f846f3a8 Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/delegation-pillars.png differ diff --git a/tests/govtool-frontend/playwright/docs/govtool-playwright-project.excalidraw b/tests/govtool-frontend/playwright/docs/govtool-playwright-project.excalidraw new file mode 100644 index 000000000..14f837758 --- /dev/null +++ b/tests/govtool-frontend/playwright/docs/govtool-playwright-project.excalidraw @@ -0,0 +1,5345 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "CvlMGXyYRtgct1OWYV76r", + "type": "text", + "x": 2064.4459823892116, + "y": 39.82988384088645, + "width": 184, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0N", + "roundness": null, + "seed": 1088036333, + "version": 358, + "versionNonce": 1989742531, + "isDeleted": false, + "boundElements": [], + "updated": 1746168602542, + "link": null, + "locked": false, + "text": "proposal pillars", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "proposal pillars", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "dDRRlMFNRVNwapnzIWKAy", + "type": "text", + "x": 237.44018555837454, + "y": 88.8443621151659, + "width": 184, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1I4", + "roundness": null, + "seed": 1802923683, + "version": 206, + "versionNonce": 2065924461, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "Delegation Pillars", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Delegation Pillars", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "miLqnBqtsyQYMh6Y6PG3h", + "type": "rectangle", + "x": 224.31512825309034, + "y": 380.01682399082, + "width": 200.5938568750449, + "height": 39.623477901243405, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "odX7bnXf4mBGTw_RdSAQD", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1I8", + "roundness": { + "type": 3 + }, + "seed": 1472309891, + "version": 105, + "versionNonce": 1332399053, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "DMbQ_xl3pJLv7gXasOBO3", + "type": "text", + "x": 235.45923141281503, + "y": 389.94622609730317, + "width": 175.4403533935547, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "odX7bnXf4mBGTw_RdSAQD", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1IC", + "roundness": null, + "seed": 1688592451, + "version": 69, + "versionNonce": 85576237, + "isDeleted": false, + "boundElements": [ + { + "id": "TgYtXLkdDrMD4TlaxAOmB", + "type": "arrow" + }, + { + "id": "sorhjXoApmDk7n9Lg2pOT", + "type": "arrow" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "Ada holder auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Ada holder auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "e-Fc_aaTdPq7EZ2Oees5n", + "type": "rectangle", + "x": 381.71459565604323, + "y": 270.2056738247015, + "width": 171.80883157793073, + "height": 39.55555555555556, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "mnbVwkhK-Meg5zi1AUvsE", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1IG", + "roundness": { + "type": 3 + }, + "seed": 421968291, + "version": 216, + "versionNonce": 532938061, + "isDeleted": false, + "boundElements": [ + { + "id": "TgYtXLkdDrMD4TlaxAOmB", + "type": "arrow" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "oTAnJEG6QKYM772RbZImD", + "type": "text", + "x": 402.3164475078951, + "y": 278.74734049136816, + "width": 129.08827209472656, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "mnbVwkhK-Meg5zi1AUvsE", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1IK", + "roundness": null, + "seed": 60310541, + "version": 194, + "versionNonce": 642829229, + "isDeleted": false, + "boundElements": [ + { + "id": "-S5GYTWWberUKKpLZZ8rE", + "type": "arrow" + }, + { + "id": "60yYoVmbOn5FmAGFXlmSi", + "type": "arrow" + }, + { + "id": "TgYtXLkdDrMD4TlaxAOmB", + "type": "arrow" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "wallet bootstrap", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "wallet bootstrap", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "vxoFRSKeptQ86tOiL0bi5", + "type": "rectangle", + "x": 514.0283032455059, + "y": 355.9226087527971, + "width": 141.15864002317983, + "height": 36.52789369020877, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2QzRgnvDN1lp6itqKLDlU", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1IO", + "roundness": { + "type": 3 + }, + "seed": 455774915, + "version": 107, + "versionNonce": 289082669, + "isDeleted": false, + "boundElements": [], + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "ZoMuyLXX60DlUN-q0tFCt", + "type": "text", + "x": 537.5547432493693, + "y": 364.59024454369415, + "width": 88.52816772460938, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2QzRgnvDN1lp6itqKLDlU", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1IS", + "roundness": null, + "seed": 1764851331, + "version": 91, + "versionNonce": 437968781, + "isDeleted": false, + "boundElements": [ + { + "id": "A8rlTiv5S7s_LyeyGsaoX", + "type": "arrow" + }, + { + "id": "60yYoVmbOn5FmAGFXlmSi", + "type": "arrow" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "dRep setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "dRep setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "gk75Snen_OmbCyKd2B8eg", + "type": "rectangle", + "x": 502.5243156150025, + "y": 438.2368658434938, + "width": 164.06596318483605, + "height": 42.719062112278095, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "vl1D-Xx4LLhHe4yqmgBeo", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1IV", + "roundness": { + "type": 3 + }, + "seed": 1607813197, + "version": 127, + "versionNonce": 842567341, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "lCeTlFWDta38B4V8mCO1s", + "type": "text", + "x": 519.8595871967965, + "y": 448.7618521610116, + "width": 130.83226013183594, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "vl1D-Xx4LLhHe4yqmgBeo", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1IZ", + "roundness": null, + "seed": 385863661, + "version": 95, + "versionNonce": 317468941, + "isDeleted": false, + "boundElements": [ + { + "id": "A8rlTiv5S7s_LyeyGsaoX", + "type": "arrow" + }, + { + "id": "9G-8YkDnkWAEORl-EBQly", + "type": "arrow" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "dRep auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "dRep auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "P0Xc-E3knxCB_HjPZPOjR", + "type": "rectangle", + "x": 420.9900160945237, + "y": 575.3325602923127, + "width": 149.57286708841028, + "height": 42.846966702551015, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "oMdNd6vQfldk4yFPkiVGe", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Id", + "roundness": { + "type": 3 + }, + "seed": 2075914285, + "version": 182, + "versionNonce": 1168724013, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "V0rgVb6enNugjwnPbg4O-", + "type": "text", + "x": 433.23200658096687, + "y": 584.514053157145, + "width": 120.70423889160156, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "oMdNd6vQfldk4yFPkiVGe", + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Ih", + "roundness": null, + "seed": 1776553827, + "version": 68, + "versionNonce": 1305002637, + "isDeleted": false, + "boundElements": [ + { + "id": "sorhjXoApmDk7n9Lg2pOT", + "type": "arrow" + }, + { + "id": "9G-8YkDnkWAEORl-EBQly", + "type": "arrow" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "delegation test", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "delegation test", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "TgYtXLkdDrMD4TlaxAOmB", + "type": "arrow", + "x": 420.61291342642244, + "y": 311.3431219719885, + "width": 72.87935867953507, + "height": 65.83050449568589, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Il", + "roundness": { + "type": 2 + }, + "seed": 410368237, + "version": 163, + "versionNonce": 1692998691, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822401, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -72.87935867953507, + 65.83050449568589 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "oTAnJEG6QKYM772RbZImD", + "focus": 0.2807968911463329, + "gap": 12.59578148062036 + }, + "endBinding": { + "elementId": "DMbQ_xl3pJLv7gXasOBO3", + "focus": -0.0066488631188494265, + "gap": 12.772599629628758 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "A8rlTiv5S7s_LyeyGsaoX", + "type": "arrow", + "x": 569.4564271874694, + "y": 399.8470566729089, + "width": 0.01924710261278051, + "height": 40.155157995407535, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Ip", + "roundness": { + "type": 2 + }, + "seed": 1792879117, + "version": 128, + "versionNonce": 443854691, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822401, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -0.01924710261278051, + 40.155157995407535 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ZoMuyLXX60DlUN-q0tFCt", + "focus": 0.27898367195830537, + "gap": 15.256812129214723 + }, + "endBinding": { + "elementId": "lCeTlFWDta38B4V8mCO1s", + "focus": -0.2422394583967271, + "gap": 8.759637492695163 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "sorhjXoApmDk7n9Lg2pOT", + "type": "arrow", + "x": 319.54919639807355, + "y": 421.55084198103077, + "width": 163.62114438856423, + "height": 150.72122068967104, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1It", + "roundness": { + "type": 2 + }, + "seed": 2025910285, + "version": 116, + "versionNonce": 371487395, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822401, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 163.62114438856423, + 150.72122068967104 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "DMbQ_xl3pJLv7gXasOBO3", + "focus": 0.27475153550888826, + "gap": 11.604615883727604 + }, + "endBinding": { + "elementId": "V0rgVb6enNugjwnPbg4O-", + "focus": 0.19284142620639874, + "gap": 12.241990486443115 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "9G-8YkDnkWAEORl-EBQly", + "type": "arrow", + "x": 585.4352448838, + "y": 481.0442041075424, + "width": 64.86658659380078, + "height": 95.05348059017297, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1J", + "roundness": { + "type": 2 + }, + "seed": 1666758157, + "version": 140, + "versionNonce": 1621911011, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822401, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -64.86658659380078, + 95.05348059017297 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "lCeTlFWDta38B4V8mCO1s", + "focus": -0.21269961791132033, + "gap": 12.28235194653081 + }, + "endBinding": { + "elementId": "V0rgVb6enNugjwnPbg4O-", + "focus": 0.214611235571392, + "gap": 8.416368459429691 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "gi7zTruRGxEtgR4dgNmcb", + "type": "rectangle", + "x": 393.8081903876237, + "y": 176.71103225216802, + "width": 150.7295078643312, + "height": 36.72597145932943, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1J8", + "roundness": { + "type": 3 + }, + "seed": 1277786989, + "version": 35, + "versionNonce": 1164219181, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "VAeNjPz_VGBEXARgESCkg", + "type": "text", + "x": 408.345554090275, + "y": 185.12740071159766, + "width": 118.65621948242188, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1JG", + "roundness": null, + "seed": 1639567779, + "version": 55, + "versionNonce": 1529062797, + "isDeleted": false, + "boundElements": [ + { + "id": "-S5GYTWWberUKKpLZZ8rE", + "type": "arrow" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "faucet address", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "faucet address", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "-S5GYTWWberUKKpLZZ8rE", + "type": "arrow", + "x": 461.58080648363887, + "y": 215.95030700253636, + "width": 0.28886695927292294, + "height": 51.70551302762851, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1JO", + "roundness": { + "type": 2 + }, + "seed": 1762614317, + "version": 195, + "versionNonce": 1707116835, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822402, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0.28886695927292294, + 51.70551302762851 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "VAeNjPz_VGBEXARgESCkg", + "focus": 0.10456002546555035, + "gap": 10.822906290938704 + }, + "endBinding": { + "elementId": "oTAnJEG6QKYM772RbZImD", + "focus": -0.07543461752963973, + "gap": 11.091520461203288 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "60yYoVmbOn5FmAGFXlmSi", + "type": "arrow", + "x": 492.0338736029656, + "y": 310.32896683099443, + "width": 81.36376163042473, + "height": 44.181397444477966, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "L-jyFhMZ8kv7GfIoF5lT9", + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1JV", + "roundness": { + "type": 2 + }, + "seed": 1369864653, + "version": 61, + "versionNonce": 873782371, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822402, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 81.36376163042473, + 44.181397444477966 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "oTAnJEG6QKYM772RbZImD", + "focus": 0.1756400079676742, + "gap": 11.581626339626268 + }, + "endBinding": { + "elementId": "ZoMuyLXX60DlUN-q0tFCt", + "focus": 0.45560994725420445, + "gap": 10.079880268221757 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "ru9ci3PeM3iHMSCrKzWgX", + "type": "text", + "x": 186.7481648607378, + "y": 765.181716686419, + "width": 75.87639318646666, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Jd", + "roundness": null, + "seed": 909866381, + "version": 108, + "versionNonce": 509736717, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "cleanup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cleanup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "-j6ojWeTe1CO__zRKg-dg", + "type": "rectangle", + "x": 418.8851665997795, + "y": 698.0327322202367, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Jl", + "roundness": { + "type": 3 + }, + "seed": 261673197, + "version": 111, + "versionNonce": 445222253, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "Q67Rvmmww33eHAdd35aX6" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "Q67Rvmmww33eHAdd35aX6", + "type": "text", + "x": 437.0592487510677, + "y": 708.0440886650191, + "width": 117.07223510742188, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Jt", + "roundness": null, + "seed": 1963946307, + "version": 123, + "versionNonce": 774854605, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "dRep teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-j6ojWeTe1CO__zRKg-dg", + "originalText": "dRep teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "yHv0FhftPl5_OvxNt9PCT", + "type": "rectangle", + "x": 433.7684634265054, + "y": 827.2742435645272, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1K", + "roundness": { + "type": 3 + }, + "seed": 692254179, + "version": 192, + "versionNonce": 862770733, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "MuGC_TNbU8cz2HuN-vjR0" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "MuGC_TNbU8cz2HuN-vjR0", + "type": "text", + "x": 445.54253642252013, + "y": 837.2856000093096, + "width": 129.87225341796875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1K8", + "roundness": null, + "seed": 1976582531, + "version": 211, + "versionNonce": 86739085, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "faucet teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "yHv0FhftPl5_OvxNt9PCT", + "originalText": "faucet teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "E5FXAZGXxjR6l30fQ-6T9", + "type": "rectangle", + "x": 385.2849527926519, + "y": 888.5965079983172, + "width": 271.58096171104995, + "height": 46.129179333120874, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1KG", + "roundness": { + "type": 3 + }, + "seed": 282772205, + "version": 269, + "versionNonce": 1696919277, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "Kq9AM2P_uTAiNzWcovxjw" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "Kq9AM2P_uTAiNzWcovxjw", + "type": "text", + "x": 402.33120147044247, + "y": 901.6610976648775, + "width": 237.48846435546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1KO", + "roundness": null, + "seed": 2143149389, + "version": 323, + "versionNonce": 568494413, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "generated-artificats teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "E5FXAZGXxjR6l30fQ-6T9", + "originalText": "generated-artificats teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "FPbk1GOmx_Ebt756bPyyE", + "type": "text", + "x": 32.61814109661543, + "y": 390.1584635747389, + "width": 55.52848384574423, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1KV", + "roundness": null, + "seed": 516429613, + "version": 85, + "versionNonce": 2092816301, + "isDeleted": false, + "boundElements": null, + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "setup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "XXn_zqgzE5q0NZnVvZWG1", + "type": "rectangle", + "x": 409.1922810956337, + "y": 763.8888247426227, + "width": 190.4201714436612, + "height": 38.06458966656055, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Kd", + "roundness": { + "type": 3 + }, + "seed": 1761302797, + "version": 172, + "versionNonce": 1340103181, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "OumNGiQBfUoK8PP53zIBB" + } + ], + "updated": 1746169822400, + "link": null, + "locked": false + }, + { + "id": "OumNGiQBfUoK8PP53zIBB", + "type": "text", + "x": 425.52220934676114, + "y": 772.9211195759029, + "width": 157.76031494140625, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "R9HOV_orBFW_cODzA2Zv4" + ], + "frameId": null, + "index": "b1Kl", + "roundness": null, + "seed": 1336323949, + "version": 197, + "versionNonce": 1950584941, + "isDeleted": false, + "boundElements": [], + "updated": 1746169822400, + "link": null, + "locked": false, + "text": "delegation teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "XXn_zqgzE5q0NZnVvZWG1", + "originalText": "delegation teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "TXJbok9oerE6PMQmuiuPJ", + "type": "text", + "x": 979.6245134112909, + "y": 98.25984829759815, + "width": 184, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1k4", + "roundness": null, + "seed": 1927046307, + "version": 309, + "versionNonce": 2109131651, + "isDeleted": false, + "boundElements": null, + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "Voting Pillars", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Voting Pillars", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "7tQ_mO365Cxud7q2oW32v", + "type": "rectangle", + "x": 990.3403637550907, + "y": 172.0172340661659, + "width": 150.7295078643312, + "height": 36.72597145932943, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1k8", + "roundness": { + "type": 3 + }, + "seed": 1868093027, + "version": 48, + "versionNonce": 1685611299, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "4aXQG1W7LKoOh-tLds1fl", + "type": "rectangle", + "x": 990.1297543993147, + "y": 257.84332641677076, + "width": 171.80883157793073, + "height": 39.55555555555556, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "vzZSAdRGKGjDEjJly3oEQ", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kG", + "roundness": { + "type": 3 + }, + "seed": 699400099, + "version": 196, + "versionNonce": 442894019, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "PJdjLfb59AKOtsnqQ_H2L", + "type": "text", + "x": 1010.7316062511663, + "y": 266.3849930834374, + "width": 129.08827209472656, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "vzZSAdRGKGjDEjJly3oEQ", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kK", + "roundness": null, + "seed": 2138444611, + "version": 180, + "versionNonce": 1981691491, + "isDeleted": false, + "boundElements": [ + { + "id": "h49Sm3--TfhdEzCQC8euR", + "type": "arrow" + }, + { + "id": "CTYw_0c1UVE8sworTvVUN", + "type": "arrow" + } + ], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "wallet bootstrap", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "wallet bootstrap", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "x3JR9ynzMVut29y2ifYPo", + "type": "rectangle", + "x": 1012.4444564496487, + "y": 329.8026135451862, + "width": 141.15864002317983, + "height": 36.52789369020877, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "U-8e9Xt4D0jtPYeFILL6P", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kO", + "roundness": { + "type": 3 + }, + "seed": 345871907, + "version": 166, + "versionNonce": 1158090051, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "iFBn-T_S-1BEoOY5K5Igs", + "type": "text", + "x": 1035.9708964535118, + "y": 338.47024933608327, + "width": 88.52816772460938, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "U-8e9Xt4D0jtPYeFILL6P", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kV", + "roundness": null, + "seed": 359455171, + "version": 158, + "versionNonce": 1675259107, + "isDeleted": false, + "boundElements": [ + { + "id": "S2UFdUpBpdtk4ayms7fAZ", + "type": "arrow" + }, + { + "id": "CTYw_0c1UVE8sworTvVUN", + "type": "arrow" + } + ], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "dRep setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "dRep setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "nI1025cotBW-8dNC924CN", + "type": "rectangle", + "x": 1002.3903649194351, + "y": 433.52469679931437, + "width": 164.06596318483605, + "height": 42.719062112278095, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qLBvpBfdUAwUJrFZPTEwz", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kZ", + "roundness": { + "type": 3 + }, + "seed": 785557859, + "version": 130, + "versionNonce": 363910083, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "7F6Rl4GURsSPiR6dlVPaF", + "type": "text", + "x": 1019.7256365012292, + "y": 444.04968311683217, + "width": 130.83226013183594, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qLBvpBfdUAwUJrFZPTEwz", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kd", + "roundness": null, + "seed": 639468803, + "version": 106, + "versionNonce": 948396899, + "isDeleted": false, + "boundElements": [ + { + "id": "S2UFdUpBpdtk4ayms7fAZ", + "type": "arrow" + }, + { + "id": "JQemIp_qTzagf5VbhGPtC", + "type": "arrow" + } + ], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "dRep auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "dRep auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "5I1_T4i94GCC1DdMd1AOr", + "type": "rectangle", + "x": 1035.0321263511755, + "y": 558.9536438040383, + "width": 122.89105849536713, + "height": 39.53539471405281, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "ERWwGkHTJxihwpOFrtdPP", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kl", + "roundness": { + "type": 3 + }, + "seed": 315354275, + "version": 246, + "versionNonce": 1644386883, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "w27wUl3tPZuEyrxUbCG0n", + "type": "text", + "x": 1045.4941468938002, + "y": 568.2593206184393, + "width": 100.07443859847807, + "height": 18.45423270613878, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "ERWwGkHTJxihwpOFrtdPP", + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kp", + "roundness": null, + "seed": 411852867, + "version": 199, + "versionNonce": 365238755, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": " voting test", + "fontSize": 14.763386164911024, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " voting test", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "S2UFdUpBpdtk4ayms7fAZ", + "type": "arrow", + "x": 1069.6287386884442, + "y": 373.7270614652979, + "width": 0.008652476267116072, + "height": 57.39395156617604, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1kt", + "roundness": { + "type": 2 + }, + "seed": 1458400131, + "version": 214, + "versionNonce": 2015915981, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873977, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -0.008652476267116072, + 57.39395156617604 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "iFBn-T_S-1BEoOY5K5Igs", + "focus": 0.2395186345368354, + "gap": 15.256812129214609 + }, + "endBinding": { + "elementId": "7F6Rl4GURsSPiR6dlVPaF", + "focus": -0.23732341232010531, + "gap": 12.928670085358249 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "JQemIp_qTzagf5VbhGPtC", + "type": "arrow", + "x": 1080.1137898698794, + "y": 476.33203506336304, + "width": 1.8630364083369386, + "height": 75.89430152210065, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1l", + "roundness": { + "type": 2 + }, + "seed": 1316267715, + "version": 164, + "versionNonce": 243461677, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873977, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 1.8630364083369386, + 75.89430152210065 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "7F6Rl4GURsSPiR6dlVPaF", + "focus": 0.08490439227720947, + "gap": 12.282351946530866 + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "ispmq-3yG6-gE0FE4qC2L", + "type": "text", + "x": 1004.8777274577419, + "y": 180.4336025255955, + "width": 118.65621948242188, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1l4", + "roundness": null, + "seed": 794169859, + "version": 79, + "versionNonce": 798924995, + "isDeleted": false, + "boundElements": [ + { + "id": "h49Sm3--TfhdEzCQC8euR", + "type": "arrow" + } + ], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "faucet address", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "faucet address", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "h49Sm3--TfhdEzCQC8euR", + "type": "arrow", + "x": 1066.714892717877, + "y": 212.56882755250876, + "width": 0.8013618030183807, + "height": 38.74661622301787, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1l8", + "roundness": { + "type": 2 + }, + "seed": 1600838051, + "version": 164, + "versionNonce": 1402275565, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873978, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0.8013618030183807, + 38.74661622301787 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ispmq-3yG6-gE0FE4qC2L", + "focus": -0.03445460197968729, + "gap": 12.135225026913275 + }, + "endBinding": { + "elementId": "PJdjLfb59AKOtsnqQ_H2L", + "focus": -0.1118284100169315, + "gap": 15.069549307910762 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "CTYw_0c1UVE8sworTvVUN", + "type": "arrow", + "x": 1070.3454000711633, + "y": 296.8687450524696, + "width": 2.501419555597977, + "height": 33.35226074130412, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "wHoHk0vU75VAIToj8Hmpw", + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1lG", + "roundness": { + "type": 2 + }, + "seed": 1448343491, + "version": 102, + "versionNonce": 1879568301, + "isDeleted": false, + "boundElements": null, + "updated": 1746169873978, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 2.501419555597977, + 33.35226074130412 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "PJdjLfb59AKOtsnqQ_H2L", + "focus": 0.09903835193336152, + "gap": 10.483751969032198 + }, + "endBinding": { + "elementId": "iFBn-T_S-1BEoOY5K5Igs", + "focus": -0.1337240904823293, + "gap": 8.249243542309557 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "lV5XVnDx-8OuL6RMUUiQf", + "type": "rectangle", + "x": 1028.7850612151497, + "y": 725.1853614043058, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1lK", + "roundness": { + "type": 3 + }, + "seed": 1350613453, + "version": 171, + "versionNonce": 874686275, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "-tJShMNoGbIm3wylcRmBN" + } + ], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "-tJShMNoGbIm3wylcRmBN", + "type": "text", + "x": 1046.959143366438, + "y": 735.1967178490883, + "width": 117.07223510742188, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1lO", + "roundness": null, + "seed": 155318317, + "version": 184, + "versionNonce": 1618134755, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "dRep teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lV5XVnDx-8OuL6RMUUiQf", + "originalText": "dRep teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "EbR3n-smuT98cvlWUqam0", + "type": "rectangle", + "x": 1031.2425667968225, + "y": 785.168501898108, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1lV", + "roundness": { + "type": 3 + }, + "seed": 669841571, + "version": 197, + "versionNonce": 954069635, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "to7sQSFddknHU2HQbWkdC" + } + ], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "to7sQSFddknHU2HQbWkdC", + "type": "text", + "x": 1043.0166397928374, + "y": 795.1798583428905, + "width": 129.87225341796875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1lZ", + "roundness": null, + "seed": 2108419139, + "version": 217, + "versionNonce": 505588259, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "faucet teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "EbR3n-smuT98cvlWUqam0", + "originalText": "faucet teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "lJyjOvo9IyjOXHpibxj58", + "type": "rectangle", + "x": 988.740873789052, + "y": 853.3506387174813, + "width": 271.58096171104995, + "height": 46.129179333120874, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1ld", + "roundness": { + "type": 3 + }, + "seed": 2112945293, + "version": 279, + "versionNonce": 1429171651, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "8SykaZ9XzQtXE8Pb_FANo" + } + ], + "updated": 1746169873923, + "link": null, + "locked": false + }, + { + "id": "8SykaZ9XzQtXE8Pb_FANo", + "type": "text", + "x": 1005.7871224668426, + "y": 866.4152283840417, + "width": 237.48846435546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1ll", + "roundness": null, + "seed": 219931373, + "version": 334, + "versionNonce": 19053923, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "generated-artificats teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lJyjOvo9IyjOXHpibxj58", + "originalText": "generated-artificats teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "biPPwl6WS0F6UVh7cnD6f", + "type": "text", + "x": 864.1527373880648, + "y": 347.14894807326954, + "width": 55.52848384574423, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1lp", + "roundness": null, + "seed": 1661236675, + "version": 98, + "versionNonce": 1565202691, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "setup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "6C_jkAOfg9yflwsWyzNg7", + "type": "text", + "x": 862.2550867060215, + "y": 771.4766405437758, + "width": 75.87639318646666, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "POq3fEVW9Y8UQCKucsPr3" + ], + "frameId": null, + "index": "b1lt", + "roundness": null, + "seed": 138838467, + "version": 109, + "versionNonce": 925302947, + "isDeleted": false, + "boundElements": [], + "updated": 1746169873923, + "link": null, + "locked": false, + "text": "cleanup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cleanup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "NiDwhOx8Br3IOdX0FiMMv", + "type": "text", + "x": 1664.10903103645, + "y": 177.4145976713013, + "width": 195.97850251567476, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1ltV", + "roundness": null, + "seed": 316472941, + "version": 160, + "versionNonce": 716832899, + "isDeleted": false, + "boundElements": null, + "updated": 1746169783179, + "link": null, + "locked": false, + "text": "proposal discussion (pd)", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "proposal discussion (pd)", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "YhPWd2S6d6FML8u1QNGuj", + "type": "rectangle", + "x": 1624.0294208302619, + "y": 344.89797042718277, + "width": 138.94661550209227, + "height": 48.32925756594523, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lu", + "roundness": { + "type": 3 + }, + "seed": 1947257133, + "version": 130, + "versionNonce": 692096803, + "isDeleted": false, + "boundElements": [ + { + "id": "CMCSzoaBQVXO0DeGkQeET", + "type": "arrow" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false + }, + { + "id": "P_11j4raLqj-mXAO9l4H0", + "type": "text", + "x": 1638.5281981000453, + "y": 359.3967476969663, + "width": 110.46421813964844, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lv", + "roundness": null, + "seed": 1665698243, + "version": 133, + "versionNonce": 1949149325, + "isDeleted": false, + "boundElements": [ + { + "id": "CMCSzoaBQVXO0DeGkQeET", + "type": "arrow" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "pd auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "pd auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "qyyN89gtZxJgJpTiwCBIe", + "type": "rectangle", + "x": 1837.8863855595698, + "y": 347.31443330548, + "width": 134.11368974549802, + "height": 41.07986893105351, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lvV", + "roundness": { + "type": 3 + }, + "seed": 590847661, + "version": 83, + "versionNonce": 1833480899, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "BeldCYz0Nm8ZiZsslh97f" + }, + { + "id": "_zgF5EtzTqQ_AGrixy7CQ", + "type": "arrow" + }, + { + "id": "QH3cFb2CMVKpZ0-8S2EF9", + "type": "arrow" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false + }, + { + "id": "BeldCYz0Nm8ZiZsslh97f", + "type": "text", + "x": 1847.7591255128852, + "y": 357.85436777100676, + "width": 114.36820983886719, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lw", + "roundness": null, + "seed": 1188071405, + "version": 41, + "versionNonce": 1860374253, + "isDeleted": false, + "boundElements": null, + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "proposal setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "qyyN89gtZxJgJpTiwCBIe", + "originalText": "proposal setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "tO9rMD_2ulIQtNzbOxWBQ", + "type": "rectangle", + "x": 1806.4723681417054, + "y": 493.5104374424645, + "width": 209.02403897271367, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lx", + "roundness": { + "type": 3 + }, + "seed": 1887276621, + "version": 83, + "versionNonce": 801858147, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "gaMIHa5lkxvqE005CyAaS" + }, + { + "id": "_zgF5EtzTqQ_AGrixy7CQ", + "type": "arrow" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false + }, + { + "id": "gaMIHa5lkxvqE005CyAaS", + "type": "text", + "x": 1814.7841999449568, + "y": 508.5104374424645, + "width": 192.40037536621094, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lxV", + "roundness": null, + "seed": 1178931427, + "version": 89, + "versionNonce": 249342285, + "isDeleted": false, + "boundElements": null, + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "proposal submission test", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tO9rMD_2ulIQtNzbOxWBQ", + "originalText": "proposal submission test", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "_zgF5EtzTqQ_AGrixy7CQ", + "type": "arrow", + "x": 1897.2558858785217, + "y": 391.4261778232293, + "width": 4.341716051535286, + "height": 97.85939801462325, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1ly", + "roundness": { + "type": 2 + }, + "seed": 338268195, + "version": 128, + "versionNonce": 1503075843, + "isDeleted": false, + "boundElements": null, + "updated": 1746168653727, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 4.341716051535286, + 97.85939801462325 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "qyyN89gtZxJgJpTiwCBIe", + "focus": 0.12848891399372414, + "gap": 3.031875586695776 + }, + "endBinding": { + "elementId": "tO9rMD_2ulIQtNzbOxWBQ", + "focus": -0.07659608544056724, + "gap": 4.224861604611931 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "VXKtb6mSip-Tkv5-hD3BD", + "type": "rectangle", + "x": 1547.9108401638982, + "y": 493.5104374424646, + "width": 217.48165904675378, + "height": 51.9539518833912, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lz", + "roundness": { + "type": 3 + }, + "seed": 1027349571, + "version": 66, + "versionNonce": 91486125, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "Efql8pgMYlg9coT8hnMG2" + }, + { + "id": "CMCSzoaBQVXO0DeGkQeET", + "type": "arrow" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false + }, + { + "id": "Efql8pgMYlg9coT8hnMG2", + "type": "text", + "x": 1561.323483652119, + "y": 509.48741338416016, + "width": 190.6563720703125, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1lzV", + "roundness": null, + "seed": 819594861, + "version": 56, + "versionNonce": 900359587, + "isDeleted": false, + "boundElements": null, + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "proposal discussion test", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "VXKtb6mSip-Tkv5-hD3BD", + "originalText": "proposal discussion test", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "CMCSzoaBQVXO0DeGkQeET", + "type": "arrow", + "x": 1685.649224226842, + "y": 395.64369087142535, + "width": 47.12102612679655, + "height": 99.0749780101878, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1m", + "roundness": { + "type": 2 + }, + "seed": 425043811, + "version": 84, + "versionNonce": 483555853, + "isDeleted": false, + "boundElements": null, + "updated": 1746168653727, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -47.12102612679655, + 99.0749780101878 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "P_11j4raLqj-mXAO9l4H0", + "focus": -0.07288464756735433, + "gap": 14 + }, + "endBinding": { + "elementId": "VXKtb6mSip-Tkv5-hD3BD", + "focus": -0.24694287278700527, + "gap": 1.2082314391485625 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "EOhSx1Abcv5hAzneKhpkl", + "type": "rectangle", + "x": 1766.9324541328078, + "y": 762.3667186562892, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1m4", + "roundness": { + "type": 3 + }, + "seed": 488048205, + "version": 204, + "versionNonce": 724810051, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "ybd-ho0-VX2Q6ioFnR60u" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false + }, + { + "id": "ybd-ho0-VX2Q6ioFnR60u", + "type": "text", + "x": 1778.7065271288227, + "y": 772.3780751010717, + "width": 129.87225341796875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1m8", + "roundness": null, + "seed": 1985655981, + "version": 225, + "versionNonce": 502378605, + "isDeleted": false, + "boundElements": [], + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "faucet teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "EOhSx1Abcv5hAzneKhpkl", + "originalText": "faucet teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "BILraYNko12lPeeUc98kF", + "type": "rectangle", + "x": 1728.4295703025077, + "y": 838.3448283484134, + "width": 271.58096171104995, + "height": 46.129179333120874, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1mG", + "roundness": { + "type": 3 + }, + "seed": 956853229, + "version": 293, + "versionNonce": 932288739, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "boekPdLphSvJve8uKS2BP" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false + }, + { + "id": "boekPdLphSvJve8uKS2BP", + "type": "text", + "x": 1745.4758189802983, + "y": 851.4094180149739, + "width": 237.48846435546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1mO", + "roundness": null, + "seed": 105801293, + "version": 348, + "versionNonce": 1989876429, + "isDeleted": false, + "boundElements": [], + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "generated-artificats teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "BILraYNko12lPeeUc98kF", + "originalText": "generated-artificats teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "s4-LFG9mAIwpsA1kF-hz4", + "type": "rectangle", + "x": 1824.3851924558735, + "y": 261.48150336659694, + "width": 150.7295078643312, + "height": 36.72597145932943, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "giXqnPxBxedjJ2NkkGdi0", + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1mV", + "roundness": { + "type": 3 + }, + "seed": 1317457379, + "version": 77, + "versionNonce": 676496515, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "e4_ecXdQuVpMPicMl2EDP" + }, + { + "id": "QH3cFb2CMVKpZ0-8S2EF9", + "type": "arrow" + } + ], + "updated": 1746168653727, + "link": null, + "locked": false + }, + { + "id": "e4_ecXdQuVpMPicMl2EDP", + "type": "text", + "x": 1840.421836646828, + "y": 269.84448909626167, + "width": 118.65621948242188, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "giXqnPxBxedjJ2NkkGdi0", + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1mZ", + "roundness": null, + "seed": 1923706563, + "version": 47, + "versionNonce": 526924077, + "isDeleted": false, + "boundElements": null, + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "faucet address", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "s4-LFG9mAIwpsA1kF-hz4", + "originalText": "faucet address", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "QH3cFb2CMVKpZ0-8S2EF9", + "type": "arrow", + "x": 1899.7499463880392, + "y": 301.1700201286413, + "width": 1.066276551619012, + "height": 43.71733861637824, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1md", + "roundness": { + "type": 2 + }, + "seed": 1864381219, + "version": 88, + "versionNonce": 355793955, + "isDeleted": false, + "boundElements": null, + "updated": 1746168653727, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -1.066276551619012, + 43.71733861637824 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "s4-LFG9mAIwpsA1kF-hz4", + "focus": -0.006860794725439379, + "gap": 2.9625453027148865 + }, + "endBinding": { + "elementId": "qyyN89gtZxJgJpTiwCBIe", + "focus": -0.10094659153297024, + "gap": 2.4270745604604826 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "_-1mpv1wSnrTiTXV24OYz", + "type": "text", + "x": 1513.6310709029622, + "y": 365.22832420793014, + "width": 55.52848384574423, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1ml", + "roundness": null, + "seed": 889620963, + "version": 107, + "versionNonce": 1103268749, + "isDeleted": false, + "boundElements": [], + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "setup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "XQTB7fQnksYlbSfa-13lj", + "type": "text", + "x": 1596.0093475609597, + "y": 794.3806577235684, + "width": 75.87639318646666, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "2mlKkGYjVTYQQCGd8n0do" + ], + "frameId": null, + "index": "b1mt", + "roundness": null, + "seed": 916528077, + "version": 139, + "versionNonce": 438796227, + "isDeleted": false, + "boundElements": [], + "updated": 1746168653727, + "link": null, + "locked": false, + "text": "cleanup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cleanup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "kzdXG96ymh5I68V0UDNP6", + "type": "text", + "x": 3230.519042783522, + "y": 175.27080619859467, + "width": 184, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1o8", + "roundness": null, + "seed": 1273711213, + "version": 448, + "versionNonce": 20735683, + "isDeleted": false, + "boundElements": [], + "updated": 1746169815956, + "link": null, + "locked": false, + "text": "Outcomes Pillars", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Outcomes Pillars", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "58SeZzOFvmfXVlMQUBK5Z", + "type": "rectangle", + "x": 3213.6321925861503, + "y": 290.9382780147972, + "width": 150.7295078643312, + "height": 36.72597145932943, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1oG", + "roundness": { + "type": 3 + }, + "seed": 242370701, + "version": 184, + "versionNonce": 1849223949, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false + }, + { + "id": "NqWsodf2D7hnfWVwDiP4n", + "type": "text", + "x": 3228.1695562888017, + "y": 299.3546464742268, + "width": 124.83224487304688, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "tiFckONBsM5N7Kir1IB4o", + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1oO", + "roundness": null, + "seed": 395554541, + "version": 224, + "versionNonce": 1583929411, + "isDeleted": false, + "boundElements": [ + { + "id": "A3t-6R1b4ybkPPwLfgGVI", + "type": "arrow" + } + ], + "updated": 1746168696351, + "link": null, + "locked": false, + "text": "user auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "user auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "A3t-6R1b4ybkPPwLfgGVI", + "type": "arrow", + "x": 3292.3920272851246, + "y": 331.48987150114004, + "width": 2.534044657287268, + "height": 46.137394379573095, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "tiFckONBsM5N7Kir1IB4o", + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1oV", + "roundness": { + "type": 2 + }, + "seed": 410601805, + "version": 691, + "versionNonce": 996278637, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 2.534044657287268, + 46.137394379573095 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "NqWsodf2D7hnfWVwDiP4n", + "focus": -0.009379699117277164, + "gap": 12.135225026913247 + }, + "endBinding": { + "elementId": "CHUEHAspg1ghHzOMverkM", + "focus": 0.07516920688692041, + "gap": 14.474358830854499 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "si3K1n6qdXgSmAxdgeN_q", + "type": "rectangle", + "x": 3232.933080171182, + "y": 383.719795166736, + "width": 122.89105849536713, + "height": 39.53539471405281, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qBVL2k53skLSRvF0hhxwq", + "tiFckONBsM5N7Kir1IB4o", + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1od", + "roundness": { + "type": 3 + }, + "seed": 1365963171, + "version": 376, + "versionNonce": 617273315, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false + }, + { + "id": "CHUEHAspg1ghHzOMverkM", + "type": "text", + "x": 3236.9281698268205, + "y": 392.10162471156764, + "width": 110.23675856374139, + "height": 18.45423270613878, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qBVL2k53skLSRvF0hhxwq", + "tiFckONBsM5N7Kir1IB4o", + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1ol", + "roundness": null, + "seed": 386057539, + "version": 359, + "versionNonce": 64572365, + "isDeleted": false, + "boundElements": [ + { + "id": "A3t-6R1b4ybkPPwLfgGVI", + "type": "arrow" + } + ], + "updated": 1746168696351, + "link": null, + "locked": false, + "text": " outcome test", + "fontSize": 14.763386164911024, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " outcome test", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "CSusFxcOt7NERZ7Oafcn4", + "type": "text", + "x": 3249.1100932099653, + "y": 257.7881401406984, + "width": 75.75547610469016, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1ot", + "roundness": null, + "seed": 638225155, + "version": 160, + "versionNonce": 973857667, + "isDeleted": false, + "boundElements": null, + "updated": 1746168696351, + "link": null, + "locked": false, + "text": "logged In", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "logged In", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "XPwIk6-SBetz8WbpLDdA6", + "type": "rectangle", + "x": 3432.4840903981712, + "y": 287.9081953404193, + "width": 122.89105849536713, + "height": 39.53539471405281, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "oZ50807NykyXBySxbrDcI", + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1p", + "roundness": { + "type": 3 + }, + "seed": 964113379, + "version": 383, + "versionNonce": 666389037, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false + }, + { + "id": "pcrI_LSYT2cU1KlODWpo9", + "type": "text", + "x": 3436.4791800538105, + "y": 296.290024885251, + "width": 110.23675856374139, + "height": 18.45423270613878, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "oZ50807NykyXBySxbrDcI", + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1pG", + "roundness": null, + "seed": 818724739, + "version": 364, + "versionNonce": 107641635, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false, + "text": " outcome test", + "fontSize": 14.763386164911024, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " outcome test", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "QIaU0iSK0nlWOb7ze8ebu", + "type": "text", + "x": 3442.194172549969, + "y": 254.25507102768418, + "width": 95.1562687656472, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1pV", + "roundness": null, + "seed": 2199011, + "version": 193, + "versionNonce": 1206418573, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false, + "text": "logged out", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "logged out", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "i2KykArUmkMsha5i8gRGI", + "type": "text", + "x": 3095.2683195083855, + "y": 296.3544220942838, + "width": 55.52848384574423, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "CCt5NF_oIQHnQU1PdUqCS", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1pl", + "roundness": null, + "seed": 605698819, + "version": 211, + "versionNonce": 1716854467, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false, + "text": "setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "setup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "54NxMecq228W2FDLxdSuT", + "type": "rectangle", + "x": 3243.694058472553, + "y": 488.2377495290043, + "width": 271.58096171104995, + "height": 46.129179333120874, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1q", + "roundness": { + "type": 3 + }, + "seed": 1843131789, + "version": 424, + "versionNonce": 740516589, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "HXkAcZ71bmZ99j2vEF_14" + } + ], + "updated": 1746168696351, + "link": null, + "locked": false + }, + { + "id": "HXkAcZ71bmZ99j2vEF_14", + "type": "text", + "x": 3260.7403071503436, + "y": 501.30233919556474, + "width": 237.48846435546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1qV", + "roundness": null, + "seed": 390052845, + "version": 480, + "versionNonce": 610946659, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false, + "text": "generated-artificats teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "54NxMecq228W2FDLxdSuT", + "originalText": "generated-artificats teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "isviwU-RNd0xjrcgpAxNT", + "type": "text", + "x": 3083.6545039660355, + "y": 505.48436901343734, + "width": 75.87639318646666, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "SvaRuvs-ENljSYhvlQqtF", + "HzwBUTQ1h_5FpRq4CNGPr" + ], + "frameId": null, + "index": "b1r", + "roundness": null, + "seed": 1816246317, + "version": 157, + "versionNonce": 1460963501, + "isDeleted": false, + "boundElements": [], + "updated": 1746168696351, + "link": null, + "locked": false, + "text": "cleanup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cleanup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "0cE2zRMYHKnU0njGNhdsh", + "type": "rectangle", + "x": 3839.220257169134, + "y": 235.70184124487358, + "width": 150.7295078643312, + "height": 36.72597145932943, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1s", + "roundness": { + "type": 3 + }, + "seed": 530661571, + "version": 190, + "versionNonce": 457691181, + "isDeleted": false, + "boundElements": [], + "updated": 1746168699215, + "link": null, + "locked": false + }, + { + "id": "xYJSU0wf-fmDsry4MRfBO", + "type": "text", + "x": 3853.7576208717855, + "y": 244.11820970430315, + "width": 124.83224487304688, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qqot1-WRhj3tS5SqWMmGt", + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1t", + "roundness": null, + "seed": 1675767907, + "version": 232, + "versionNonce": 2046711075, + "isDeleted": false, + "boundElements": [ + { + "id": "uQ7SqGGCOwLZ32FcqudrZ", + "type": "arrow" + } + ], + "updated": 1746168699215, + "link": null, + "locked": false, + "text": "user auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "user auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "uQ7SqGGCOwLZ32FcqudrZ", + "type": "arrow", + "x": 3918.159410413129, + "y": 276.25343473121643, + "width": 2.867185752304067, + "height": 47.439916126801705, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qqot1-WRhj3tS5SqWMmGt", + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1u", + "roundness": { + "type": 2 + }, + "seed": 1034169347, + "version": 728, + "versionNonce": 1805075085, + "isDeleted": false, + "boundElements": [], + "updated": 1746168699215, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 2.867185752304067, + 47.439916126801705 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "xYJSU0wf-fmDsry4MRfBO", + "focus": -0.01028003073454243, + "gap": 12.135225026913304 + }, + "endBinding": { + "elementId": "dxodlUn8yWkRuWBQNOEj4", + "focus": 0.07495498326987578, + "gap": 14.474358830854499 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "aMTxmmttzsa94u5d208cz", + "type": "rectangle", + "x": 3857.8698838805517, + "y": 328.4833583968124, + "width": 122.89105849536713, + "height": 39.53539471405281, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "g8fHZZ646W-6jcCdIUW_b", + "qqot1-WRhj3tS5SqWMmGt", + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1v", + "roundness": { + "type": 3 + }, + "seed": 1894101923, + "version": 383, + "versionNonce": 777894083, + "isDeleted": false, + "boundElements": [], + "updated": 1746168699215, + "link": null, + "locked": false + }, + { + "id": "dxodlUn8yWkRuWBQNOEj4", + "type": "text", + "x": 3863.1674952834187, + "y": 338.1677096888726, + "width": 110.23675856374139, + "height": 18.45423270613878, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "g8fHZZ646W-6jcCdIUW_b", + "qqot1-WRhj3tS5SqWMmGt", + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1w", + "roundness": null, + "seed": 1037387587, + "version": 381, + "versionNonce": 973695213, + "isDeleted": false, + "boundElements": [ + { + "id": "uQ7SqGGCOwLZ32FcqudrZ", + "type": "arrow" + } + ], + "updated": 1746168699215, + "link": null, + "locked": false, + "text": " login tests", + "fontSize": 14.763386164911024, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " login tests", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "FDOINi3I8XMgSJufivRW_", + "type": "text", + "x": 3819.6244967713324, + "y": 176.63468641942583, + "width": 75.75547610469016, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1x", + "roundness": null, + "seed": 1523672803, + "version": 180, + "versionNonce": 1111456227, + "isDeleted": false, + "boundElements": [], + "updated": 1746169818030, + "link": null, + "locked": false, + "text": "logged In", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "logged In", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "BnGhjCppl1cHwFb3CTDy5", + "type": "text", + "x": 3735.273357917632, + "y": 246.9323189977893, + "width": 55.52848384574423, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1y", + "roundness": null, + "seed": 1865844995, + "version": 183, + "versionNonce": 405259085, + "isDeleted": false, + "boundElements": [], + "updated": 1746168699215, + "link": null, + "locked": false, + "text": "setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "setup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "jQLcnNto4b8Mt4FQX3aum", + "type": "rectangle", + "x": 3801.921991568134, + "y": 444.9641500483233, + "width": 271.58096171104995, + "height": 46.129179333120874, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b1z", + "roundness": { + "type": 3 + }, + "seed": 844261667, + "version": 397, + "versionNonce": 832742403, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "xIIXM43V7F6oJB4lH2gaO" + } + ], + "updated": 1746168699215, + "link": null, + "locked": false + }, + { + "id": "xIIXM43V7F6oJB4lH2gaO", + "type": "text", + "x": 3818.968240245925, + "y": 458.0287397148837, + "width": 237.48846435546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b20", + "roundness": null, + "seed": 1796164803, + "version": 453, + "versionNonce": 709611949, + "isDeleted": false, + "boundElements": [], + "updated": 1746168699215, + "link": null, + "locked": false, + "text": "generated-artificats teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "jQLcnNto4b8Mt4FQX3aum", + "originalText": "generated-artificats teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "xNKIDfNaGQOkbYam-QJ0x", + "type": "text", + "x": 3674.7147182253625, + "y": 459.4820410168388, + "width": 75.87639318646666, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "MIyCRLhk9HfAXL03otIJ-", + "hdn_kkkf98IHo6WKbldVl" + ], + "frameId": null, + "index": "b21", + "roundness": null, + "seed": 1724371949, + "version": 164, + "versionNonce": 1314204579, + "isDeleted": false, + "boundElements": [], + "updated": 1746168699215, + "link": null, + "locked": false, + "text": "cleanup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cleanup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "grZR6Q4vsACDPx8hwHGeK", + "type": "text", + "x": 2409.447774343792, + "y": 138.85009278244098, + "width": 164.6665260415598, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b22", + "roundness": null, + "seed": 37657635, + "version": 404, + "versionNonce": 1097142765, + "isDeleted": false, + "boundElements": null, + "updated": 1746169808942, + "link": null, + "locked": false, + "text": "budget proposal (bp)", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "budget proposal (bp)", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "hYw-tp47epS5USubP9Gze", + "type": "rectangle", + "x": 2170.0821386944867, + "y": 328.2785813398106, + "width": 138.94661550209227, + "height": 48.32925756594523, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b23", + "roundness": { + "type": 3 + }, + "seed": 1411947245, + "version": 153, + "versionNonce": 235733507, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "jdekUTG06faselj8VXoR_", + "type": "text", + "x": 2184.58091596427, + "y": 342.77735860959416, + "width": 109.66421508789062, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b24", + "roundness": null, + "seed": 1267774797, + "version": 170, + "versionNonce": 700696995, + "isDeleted": false, + "boundElements": [ + { + "id": "X1_WP81tKQ_Hu1MN93EyV", + "type": "arrow" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "bp auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bp auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "j_fEvEaOO_qWKeusnj_in", + "type": "rectangle", + "x": 2383.9391034237947, + "y": 330.69504421810785, + "width": 134.11368974549802, + "height": 41.07986893105351, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b25", + "roundness": { + "type": 3 + }, + "seed": 667321261, + "version": 107, + "versionNonce": 2007104739, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "OGCvqAVL0jQzZD0Krk-sM" + }, + { + "id": "o8obZnO-jo7jsvMQrrjxO", + "type": "arrow" + }, + { + "id": "x0Z6jpE1ob9KqrfA97xHZ", + "type": "arrow" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "OGCvqAVL0jQzZD0Krk-sM", + "type": "text", + "x": 2394.795844536778, + "y": 341.2349786836346, + "width": 112.40020751953125, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b26", + "roundness": null, + "seed": 1827898893, + "version": 80, + "versionNonce": 1354131587, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "bp dRep setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "j_fEvEaOO_qWKeusnj_in", + "originalText": "bp dRep setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "r4AwpuDLlQVcldG57lpZy", + "type": "rectangle", + "x": 2288.3030813821206, + "y": 457.4646218550605, + "width": 139.63679005107127, + "height": 37.802224930953116, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b27", + "roundness": { + "type": 3 + }, + "seed": 1290004877, + "version": 146, + "versionNonce": 604435299, + "isDeleted": false, + "boundElements": null, + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "ggYMmo36CAAxYBUjczP0a", + "type": "text", + "x": 2306.046982880323, + "y": 466.72230959325304, + "width": 103.88819885253906, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b28", + "roundness": null, + "seed": 1649828877, + "version": 113, + "versionNonce": 1111002883, + "isDeleted": false, + "boundElements": [ + { + "id": "X1_WP81tKQ_Hu1MN93EyV", + "type": "arrow" + }, + { + "id": "o8obZnO-jo7jsvMQrrjxO", + "type": "arrow" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "bp dRep test", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bp dRep test", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "X1_WP81tKQ_Hu1MN93EyV", + "type": "arrow", + "x": 2256.6726482766294, + "y": 376.4598541458753, + "width": 97.97719522920488, + "height": 77.91887179645431, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b29", + "roundness": { + "type": 2 + }, + "seed": 2100046403, + "version": 148, + "versionNonce": 1169748877, + "isDeleted": false, + "boundElements": null, + "updated": 1746169803294, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 97.97719522920488, + 77.91887179645431 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "jdekUTG06faselj8VXoR_", + "focus": 0.18572956386144696, + "gap": 13.682495536281124 + }, + "endBinding": { + "elementId": "ggYMmo36CAAxYBUjczP0a", + "focus": 0.3836762073785214, + "gap": 12.34358365092345 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "o8obZnO-jo7jsvMQrrjxO", + "type": "arrow", + "x": 2452.627038735039, + "y": 372.6024842549617, + "width": 63.26086621098284, + "height": 84.09066362191606, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2A", + "roundness": { + "type": 2 + }, + "seed": 593698349, + "version": 149, + "versionNonce": 676410445, + "isDeleted": false, + "boundElements": null, + "updated": 1746169803294, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -63.26086621098284, + 84.09066362191606 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "j_fEvEaOO_qWKeusnj_in", + "focus": -0.21459171606928162, + "gap": 1 + }, + "endBinding": { + "elementId": "ggYMmo36CAAxYBUjczP0a", + "focus": 0.27422386923048003, + "gap": 10.029161716375256 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "VDNHFKvtn-Nee4_My9XC7", + "type": "rectangle", + "x": 2730.743899227114, + "y": 330.97220406032676, + "width": 138.94661550209227, + "height": 48.32925756594523, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2B", + "roundness": { + "type": 3 + }, + "seed": 202923683, + "version": 254, + "versionNonce": 1439681827, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "lqCQEGtbvsRF_m5PPK-P0", + "type": "text", + "x": 2746.738239535255, + "y": 343.97541829175424, + "width": 109.66421508789062, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2C", + "roundness": null, + "seed": 1400541763, + "version": 241, + "versionNonce": 20984003, + "isDeleted": false, + "boundElements": [ + { + "id": "UTt5t8OQ8PmyzHhSoqv8V", + "type": "arrow" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "bp auth setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bp auth setup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "hAisnjwZ52kf_Lr-FilcI", + "type": "rectangle", + "x": 2751.7532444216117, + "y": 451.18486634544087, + "width": 91.77877282368075, + "height": 37.802224930953116, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "zIMOfZFQX0LgxiXXm_CHk", + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2D", + "roundness": { + "type": 3 + }, + "seed": 1012823331, + "version": 237, + "versionNonce": 407313411, + "isDeleted": false, + "boundElements": [ + { + "id": "UTt5t8OQ8PmyzHhSoqv8V", + "type": "arrow" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "XpsvOh3hJ60zR1JTEhk7m", + "type": "text", + "x": 2770.2449274389924, + "y": 458.94699104527746, + "width": 58.848114013671875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "zIMOfZFQX0LgxiXXm_CHk", + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2E", + "roundness": null, + "seed": 1874450627, + "version": 211, + "versionNonce": 1504355235, + "isDeleted": false, + "boundElements": [ + { + "id": "UTt5t8OQ8PmyzHhSoqv8V", + "type": "arrow" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "bp test", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bp test", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "UTt5t8OQ8PmyzHhSoqv8V", + "type": "arrow", + "x": 2795.416634415546, + "y": 377.6579138280354, + "width": 3.1908995413177763, + "height": 65.20658597042865, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2F", + "roundness": { + "type": 2 + }, + "seed": 1428670563, + "version": 342, + "versionNonce": 81806605, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803294, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 3.1908995413177763, + 65.20658597042865 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "lqCQEGtbvsRF_m5PPK-P0", + "focus": 0.13218416757723603, + "gap": 13.68249553628118 + }, + "endBinding": { + "elementId": "XpsvOh3hJ60zR1JTEhk7m", + "focus": 0.007184146762296291, + "gap": 14 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "xig5rFD7NQcmntkuGwa1e", + "type": "rectangle", + "x": 2310.871988786348, + "y": 706.0806334242295, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2G", + "roundness": { + "type": 3 + }, + "seed": 1384573933, + "version": 167, + "versionNonce": 1746109059, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "GIU3TPyffKmc6HPlYg5oS" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "GIU3TPyffKmc6HPlYg5oS", + "type": "text", + "x": 2329.046070937636, + "y": 716.091989869012, + "width": 117.07223510742188, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2H", + "roundness": null, + "seed": 1811736141, + "version": 179, + "versionNonce": 1881553443, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "dRep teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "xig5rFD7NQcmntkuGwa1e", + "originalText": "dRep teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "ia59gXjFYbXUJOAVFJO6n", + "type": "rectangle", + "x": 2312.6263342462908, + "y": 769.6773879346026, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2I", + "roundness": { + "type": 3 + }, + "seed": 763663533, + "version": 216, + "versionNonce": 1078001091, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "QJZxZ_DZwfIZ7yBp_e_-p" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "QJZxZ_DZwfIZ7yBp_e_-p", + "type": "text", + "x": 2324.4004072423054, + "y": 779.6887443793851, + "width": 129.87225341796875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2J", + "roundness": null, + "seed": 315062029, + "version": 235, + "versionNonce": 864177507, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "faucet teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ia59gXjFYbXUJOAVFJO6n", + "originalText": "faucet teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "8DjzXoxZEcYmGbEdKROhT", + "type": "rectangle", + "x": 2720.29771537001, + "y": 726.999504556808, + "width": 153.4203994099983, + "height": 40.0227128895649, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2K", + "roundness": { + "type": 3 + }, + "seed": 195068141, + "version": 237, + "versionNonce": 1027123459, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "YychXriIHwb62q6NCNf-r" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "YychXriIHwb62q6NCNf-r", + "type": "text", + "x": 2732.0717883660245, + "y": 737.0108610015905, + "width": 129.87225341796875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2L", + "roundness": null, + "seed": 1461443405, + "version": 256, + "versionNonce": 1659015331, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "faucet teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "8DjzXoxZEcYmGbEdKROhT", + "originalText": "faucet teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "eWbV3macjLqy575dbxhHt", + "type": "rectangle", + "x": 2284.6434614866216, + "y": 846.916567068751, + "width": 271.58096171104995, + "height": 46.129179333120874, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2M", + "roundness": { + "type": 3 + }, + "seed": 1427259597, + "version": 303, + "versionNonce": 1982760003, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "xeeZ2IPqQG_Z6VDe6sq6W" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "xeeZ2IPqQG_Z6VDe6sq6W", + "type": "text", + "x": 2301.689710164412, + "y": 859.9811567353114, + "width": 237.48846435546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2N", + "roundness": null, + "seed": 806002477, + "version": 358, + "versionNonce": 251331555, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "generated-artificats teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "eWbV3macjLqy575dbxhHt", + "originalText": "generated-artificats teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "4VXnn8NRUKdeb4dhwWC5J", + "type": "rectangle", + "x": 2676.9512539093175, + "y": 802.2938797789657, + "width": 271.58096171104995, + "height": 46.129179333120874, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2O", + "roundness": { + "type": 3 + }, + "seed": 1313268269, + "version": 315, + "versionNonce": 1163300739, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "I6lSerTgWjyocB07BbBhv" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "I6lSerTgWjyocB07BbBhv", + "type": "text", + "x": 2693.997502587108, + "y": 815.3584694455261, + "width": 237.48846435546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2P", + "roundness": null, + "seed": 1357124749, + "version": 370, + "versionNonce": 729786147, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "generated-artificats teardown", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "4VXnn8NRUKdeb4dhwWC5J", + "originalText": "generated-artificats teardown", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "LLnHHzrwXuEXwuCjPcq6e", + "type": "rectangle", + "x": 2349.613306322139, + "y": 251.4828671685105, + "width": 150.7295078643312, + "height": 36.72597145932943, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "xA_DO_xatZPamK7Z9L8y6", + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2Q", + "roundness": { + "type": 3 + }, + "seed": 1640800781, + "version": 112, + "versionNonce": 132434627, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "_sQWi_ea0S7RlChwSalGD" + }, + { + "id": "x0Z6jpE1ob9KqrfA97xHZ", + "type": "arrow" + } + ], + "updated": 1746169803257, + "link": null, + "locked": false + }, + { + "id": "_sQWi_ea0S7RlChwSalGD", + "type": "text", + "x": 2365.6499505130937, + "y": 259.8458528981752, + "width": 118.65621948242188, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "xA_DO_xatZPamK7Z9L8y6", + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2R", + "roundness": null, + "seed": 291952749, + "version": 82, + "versionNonce": 1327790691, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "faucet address", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "LLnHHzrwXuEXwuCjPcq6e", + "originalText": "faucet address", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "x0Z6jpE1ob9KqrfA97xHZ", + "type": "arrow", + "x": 2427.110613357543, + "y": 292.2376604821738, + "width": 0, + "height": 36.25340275504533, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2S", + "roundness": { + "type": 2 + }, + "seed": 115320259, + "version": 137, + "versionNonce": 1207051725, + "isDeleted": false, + "boundElements": null, + "updated": 1746169803294, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 36.25340275504533 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "LLnHHzrwXuEXwuCjPcq6e", + "focus": -0.02829642494630742, + "gap": 4.0288218543338985 + }, + "endBinding": { + "elementId": "j_fEvEaOO_qWKeusnj_in", + "focus": -0.35619532926618896, + "gap": 2.20398098088873 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "H28t1CDnBrzfp3Tp6r8AJ", + "type": "text", + "x": 2170.708002934, + "y": 776.7657526323427, + "width": 75.87639318646666, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "s3d4504aVRdrVEh_kZu36", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2T", + "roundness": null, + "seed": 581624845, + "version": 156, + "versionNonce": 1795412291, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "cleanup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cleanup", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "dfF6dEnKeHq720gN3wXVP", + "type": "text", + "x": 2066.208105548032, + "y": 344.86880922719814, + "width": 55.52848384574423, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "u9yQsMVOjO06m2WHAxtx5", + "-MOQYEtto9t548L5iwlA8" + ], + "frameId": null, + "index": "b2U", + "roundness": null, + "seed": 570612781, + "version": 157, + "versionNonce": 899592419, + "isDeleted": false, + "boundElements": [], + "updated": 1746169803257, + "link": null, + "locked": false, + "text": "setup", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "setup", + "autoResize": false, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/tests/govtool-frontend/playwright/docs/image-1.png b/tests/govtool-frontend/playwright/docs/image-1.png new file mode 100644 index 000000000..0995056cf Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/image-1.png differ diff --git a/tests/govtool-frontend/playwright/docs/image-2.png b/tests/govtool-frontend/playwright/docs/image-2.png new file mode 100644 index 000000000..16e2dcec3 Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/image-2.png differ diff --git a/tests/govtool-frontend/playwright/docs/image.png b/tests/govtool-frontend/playwright/docs/image.png new file mode 100644 index 000000000..8c0647f3e Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/image.png differ diff --git a/tests/govtool-frontend/playwright/docs/loggedin.png b/tests/govtool-frontend/playwright/docs/loggedin.png new file mode 100644 index 000000000..37d20f51e Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/loggedin.png differ diff --git a/tests/govtool-frontend/playwright/docs/outcomes-pillars.png b/tests/govtool-frontend/playwright/docs/outcomes-pillars.png new file mode 100644 index 000000000..85060c9f3 Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/outcomes-pillars.png differ diff --git a/tests/govtool-frontend/playwright/docs/proposal-discussion.png b/tests/govtool-frontend/playwright/docs/proposal-discussion.png new file mode 100644 index 000000000..70e72a7be Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/proposal-discussion.png differ diff --git a/tests/govtool-frontend/playwright/docs/voting-pillars.png b/tests/govtool-frontend/playwright/docs/voting-pillars.png new file mode 100644 index 000000000..719acf56f Binary files /dev/null and b/tests/govtool-frontend/playwright/docs/voting-pillars.png differ diff --git a/tests/govtool-frontend/playwright/generate_faucet_wallet.ts b/tests/govtool-frontend/playwright/generate_faucet_wallet.ts new file mode 100644 index 000000000..f29d3bab5 --- /dev/null +++ b/tests/govtool-frontend/playwright/generate_faucet_wallet.ts @@ -0,0 +1,32 @@ +import { ShelleyWallet } from "./lib/helpers/crypto"; + +(async () => { + try { + console.log("\nGenerating your wallet... 🔐"); + const wallet = await ShelleyWallet.generate(); + const walletJson = wallet.json(); + + // Display wallet details + console.log("\n🎉 Wallet generated successfully!"); + console.log("-----------------------------------"); + console.log("💼 Wallet:", walletJson); + console.log(`🔑 Payment Private Key: ${walletJson.payment.private}`); + console.log(`🔗 Stake Public Key Hash: ${walletJson.stake.pkh}`); + console.log(`🏠 Wallet Address: ${walletJson.address}`); + console.log("-----------------------------------"); + + // Instructions for environment variables + console.log( + "\n📋 Please copy the following to your environment variables:" + ); + console.log(`1. Set FAUCET_PAYMENT_PRIVATE=${walletJson.payment.private}`); + console.log(`2. Set FAUCET_STAKE_PKH=${walletJson.stake.pkh}`); + console.log(`3. Set FAUCET_ADDRESS=${walletJson.address}`); + + console.log( + "\n🎈 All set! Please ensure this wallet is funded with a sufficient balance" + ); + } catch (error) { + console.error("\n❌ An error occurred:", error.message); + } +})(); diff --git a/tests/govtool-frontend/playwright/lib/constants/environments.ts b/tests/govtool-frontend/playwright/lib/constants/environments.ts index 1d36e6417..1882424c6 100644 --- a/tests/govtool-frontend/playwright/lib/constants/environments.ts +++ b/tests/govtool-frontend/playwright/lib/constants/environments.ts @@ -13,14 +13,12 @@ const environments = { blockfrostApiUrl: "https://cardano-" + NETWORK + ".blockfrost.io/api", apiUrl: `${SERVER_HOST_URL}/api`, docsUrl: process.env.DOCS_URL || "https://docs.gov.tools/cardano-govtool", - pdfUrl: process.env.PDF_URL || "https://dev.api.pdf.gov.tools", networkId: NETWORK === "mainnet" ? 1 : 0, faucet: { apiUrl: `https://faucet.${NETWORK}.world.dev.cardano.org`, - apiKey: process.env.FAUCET_API_KEY || "", - address: - process.env.FAUCET_ADDRESS || - "addr_test1vz0ua2vyk7r4vufmpqh5v44awg8xff26hxlwyrt3uc67maqtql3kl", + address: process.env.FAUCET_ADDRESS, + payment: { private: process.env.FAUCET_PAYMENT_PRIVATE }, + stake: { pkh: process.env.FAUCET_STAKE_PKH }, }, kuber: { apiUrl: `https://${NETWORK}.kuber.cardanoapi.io`, @@ -30,17 +28,6 @@ const environments = { metadataBucketUrl: `${CARDANO_API_METADATA_HOST_URL}/data`, lockInterceptorUrl: `${CARDANO_API_METADATA_HOST_URL}/lock`, ci: process.env.CI, - proposalFaucet: { - payment: { - private: process.env.PROPOSAL_FAUCET_PAYMENT_PRIVATE, - }, - stake: { - private: process.env.PROPOSAL_FAUCET_STAKE_PRIVATE, - }, - dRep: { - private: process.env.PROPOSAL_FAUCET_DREP_PRIVATE, - }, - }, }; export default environments; diff --git a/tests/govtool-frontend/playwright/lib/constants/proposalFaucetWallet.ts b/tests/govtool-frontend/playwright/lib/constants/proposalFaucetWallet.ts deleted file mode 100644 index 44055abf5..000000000 --- a/tests/govtool-frontend/playwright/lib/constants/proposalFaucetWallet.ts +++ /dev/null @@ -1,22 +0,0 @@ -import environments from "@constants/environments"; - -export const proposalFaucetWallet = { - payment: { - private: environments.proposalFaucet.payment.private, - public: "13904f75a8080b61cdfee163c3c22a05b3fa8f4aaa42df084a02f425548f0122", - pkh: "a37077973e85242b117341ccf59d2fb78affe3a05944b089c22583d6", - }, - stake: { - private: environments.proposalFaucet.stake.private, - public: "c2277f37f2fece309bad0d6ec1506e48b2a91f0ff4e7dcaad176891d6364aee3", - pkh: "4e641f833be7026d9948ff6ab61791123166a1c84f58fd472a6b33a5", - }, - dRep: { - private: environments.proposalFaucet.dRep.private, - public: "e24809b52036894376295a724d32d225d98b29da515d87dc0bb1a769e28c0b59", - pkh: "ff3a5ff960ffae3726c80996ebbf0b3ec3992a62ea7c7818908a8cfe", - }, - dRepId: "drep1lua9l7tql7hrwfkgpxtwh0ct8mpej2nzaf78sxys32x0udvl8a5", - address: - "addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd", -}; diff --git a/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts b/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts index 7884a5be8..529551a51 100644 --- a/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts +++ b/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts @@ -1,37 +1,35 @@ const staticWallets: StaticWallet[] = require("../_mock/wallets.json"); import { StaticWallet } from "@types"; -import { proposalFaucetWallet } from "./proposalFaucetWallet"; -export const faucetWallet = staticWallets[0]; -export const dRep01Wallet = staticWallets[1]; -export const dRep02Wallet = staticWallets[2]; -export const dRep03Wallet = staticWallets[3]; +export const dRep01Wallet = staticWallets[0]; +export const dRep02Wallet = staticWallets[1]; +export const dRep03Wallet = staticWallets[2]; -export const adaHolder01Wallet = staticWallets[4]; -export const adaHolder02Wallet = staticWallets[5]; -export const adaHolder03Wallet = staticWallets[6]; -export const adaHolder04Wallet = staticWallets[7]; -export const adaHolder05Wallet = staticWallets[8]; -export const adaHolder06Wallet = staticWallets[9]; +export const adaHolder01Wallet = staticWallets[3]; +export const adaHolder02Wallet = staticWallets[4]; +export const adaHolder03Wallet = staticWallets[5]; +export const adaHolder04Wallet = staticWallets[6]; +export const adaHolder05Wallet = staticWallets[7]; +export const adaHolder06Wallet = staticWallets[8]; // Does not takes part in transaction -export const user01Wallet: StaticWallet = staticWallets[10]; +export const user01Wallet: StaticWallet = staticWallets[9]; // Username is already set -export const proposal01Wallet: StaticWallet = staticWallets[11]; -export const proposal02Wallet: StaticWallet = staticWallets[12]; -export const proposal03Wallet: StaticWallet = staticWallets[13]; -export const proposal04Wallet: StaticWallet = staticWallets[14]; -export const proposal05Wallet: StaticWallet = staticWallets[15]; -export const proposal06Wallet: StaticWallet = staticWallets[16]; -export const proposal07Wallet: StaticWallet = staticWallets[17]; -export const proposal08Wallet: StaticWallet = staticWallets[18]; -export const proposal09Wallet: StaticWallet = staticWallets[19]; +export const proposal01Wallet: StaticWallet = staticWallets[10]; +export const proposal02Wallet: StaticWallet = staticWallets[11]; +export const proposal03Wallet: StaticWallet = staticWallets[12]; +export const proposal04Wallet: StaticWallet = staticWallets[13]; +export const proposal05Wallet: StaticWallet = staticWallets[14]; +export const proposal06Wallet: StaticWallet = staticWallets[15]; +export const proposal07Wallet: StaticWallet = staticWallets[16]; +export const proposal08Wallet: StaticWallet = staticWallets[17]; +export const proposal09Wallet: StaticWallet = staticWallets[18]; -export const budgetProposal01Wallet: StaticWallet = staticWallets[20]; -export const budgetProposal02Wallet: StaticWallet = staticWallets[21]; -export const budgetProposal03Wallet: StaticWallet = staticWallets[22]; -export const budgetProposal04Wallet: StaticWallet = staticWallets[23]; +export const budgetProposal01Wallet: StaticWallet = staticWallets[19]; +export const budgetProposal02Wallet: StaticWallet = staticWallets[20]; +export const budgetProposal03Wallet: StaticWallet = staticWallets[21]; +export const budgetProposal04Wallet: StaticWallet = staticWallets[22]; export const adaHolderWallets = [ adaHolder01Wallet, @@ -64,7 +62,5 @@ export const allStaticWallets = [ ...adaHolderWallets, user01Wallet, ...proposalWallets, - faucetWallet, - proposalFaucetWallet, ...budgetProposalDRepWallets, ]; diff --git a/tests/govtool-frontend/playwright/lib/fixtures/proposal.ts b/tests/govtool-frontend/playwright/lib/fixtures/proposal.ts index 5ae1e4b0d..d65b0cb94 100644 --- a/tests/govtool-frontend/playwright/lib/fixtures/proposal.ts +++ b/tests/govtool-frontend/playwright/lib/fixtures/proposal.ts @@ -1,7 +1,9 @@ import { proposal01AuthFile } from "@constants/auth"; +import environments from "@constants/environments"; import { proposal01Wallet } from "@constants/staticWallets"; import { test as base } from "@fixtures/walletExtension"; import { createNewPageWithWallet } from "@helpers/page"; +import { rewardAddressBech32 } from "@helpers/shellyWallet"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import ProposalSubmissionPage from "@pages/proposalSubmissionPage"; @@ -23,8 +25,13 @@ export const test = base.extend({ const proposalCreationPage = new ProposalSubmissionPage(proposalPage); await proposalCreationPage.goto(); + const receiverAddress = rewardAddressBech32( + environments.networkId, + proposal01Wallet.stake.pkh + ); + const proposalId = - await proposalCreationPage.createProposal(proposal01Wallet); + await proposalCreationPage.createProposal(receiverAddress); const proposalDetailsPage = new ProposalDiscussionDetailsPage(proposalPage); diff --git a/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts b/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts index e129edab9..86a644de1 100644 --- a/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts +++ b/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts @@ -1,4 +1,5 @@ import { downloadMetadata } from "@helpers/metadata"; +import { functionWaitedAssert } from "@helpers/waitedLoop"; import { Download, Page, expect } from "@playwright/test"; import metadataBucketService from "@services/metadataBucketService"; import { IDRepInfo } from "@types"; @@ -118,8 +119,14 @@ export default class DRepForm { await this.form.getByRole("checkbox").click(); await this.registerBtn.click(); - this.metadataDownloadBtn.click(); - const dRepMetadata = await this.downloadVoteMetadata(); + let dRepMetadata: { name: string; data: JSON }; + await functionWaitedAssert( + async () => { + this.metadataDownloadBtn.click(); + dRepMetadata = await this.downloadVoteMetadata(); + }, + { name: "download metadata" } + ); const url = await metadataBucketService.uploadMetadata( dRepMetadata.name, dRepMetadata.data @@ -130,7 +137,9 @@ export default class DRepForm { } async downloadVoteMetadata() { - const download: Download = await this.form.waitForEvent("download"); + const download: Download = await this.form.waitForEvent("download", { + timeout: 20_000, + }); return downloadMetadata(download); } @@ -160,7 +169,9 @@ export default class DRepForm { for (const err of formErrors.dRepName) { await expect(this.form.getByTestId(err)).toBeHidden(); } - const objectivesInputText = await this.objectivesInput.textContent(); + const objectivesInputText = await this.objectivesInput.textContent({ + timeout: 60_000, + }); const motivationsInputText = await this.motivationsInput.textContent(); const qualificationsInputText = await this.qualificationsInput.textContent(); @@ -174,21 +185,21 @@ export default class DRepForm { .getByTestId(formErrors.paymentAddress) .isVisible(); - expect(await this.objectivesInput.textContent({ timeout: 60_000 }), { + expect(objectivesInputText, { message: objectivesInputText !== dRepInfo.objectives && - `${dRepInfo.objectives} is not equal to ${await this.objectivesInput.textContent()}`, + `${dRepInfo.objectives} is not equal to ${objectivesInputText}`, }).toEqual(dRepInfo.objectives); - expect(await this.motivationsInput.textContent(), { + expect(motivationsInputText, { message: motivationsInputText !== dRepInfo.motivations && - `${dRepInfo.motivations} is not equal to ${await this.motivationsInput.textContent()}`, + `${dRepInfo.motivations} is not equal to ${motivationsInputText}`, }).toEqual(dRepInfo.motivations); - expect(await this.qualificationsInput.textContent(), { + expect(qualificationsInputText, { message: qualificationsInputText !== dRepInfo.qualifications && - `${dRepInfo.qualifications} is not equal to ${await this.qualificationsInput.textContent()}`, + `${dRepInfo.qualifications} is not equal to ${qualificationsInputText}`, }).toEqual(dRepInfo.qualifications); await expect(this.form.getByTestId(formErrors.links.url), { @@ -257,20 +268,20 @@ export default class DRepForm { `${dRepInfo.paymentAddress} is a valid paymentAddress`, }).toBeVisible({ timeout: 60_000 }); - expect(await this.objectivesInput.textContent(), { + expect(objectivesInputText, { message: objectivesInputText === dRepInfo.objectives && - `${dRepInfo.objectives} is equal to ${await this.objectivesInput.textContent()}`, + `${dRepInfo.objectives} is equal to ${objectivesInputText}`, }).not.toEqual(dRepInfo.objectives); - expect(await this.motivationsInput.textContent(), { + expect(motivationsInputText, { message: motivationsInputText === dRepInfo.motivations && - `${dRepInfo.motivations} is equal to ${await this.motivationsInput.textContent()}`, + `${dRepInfo.motivations} is equal to ${motivationsInputText}`, }).not.toEqual(dRepInfo.qualifications); - expect(await this.qualificationsInput.textContent(), { + expect(qualificationsInputText, { message: qualificationsInputText === dRepInfo.qualifications && - `${dRepInfo.qualifications} is equal to ${await this.qualificationsInput.textContent()}`, + `${dRepInfo.qualifications} is equal to ${qualificationsInputText}`, }).not.toEqual(dRepInfo.qualifications); await expect(this.form.getByTestId(formErrors.links.url), { diff --git a/tests/govtool-frontend/playwright/lib/helpers/cardano.ts b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts index ae9528a7b..a2b47a3ff 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/cardano.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts @@ -1,7 +1,7 @@ import environments from "@constants/environments"; import test from "@playwright/test"; import kuberService from "@services/kuberService"; -import { ProposalType, ProtocolParams } from "@types"; +import { ProposalType } from "@types"; import { allure } from "allure-playwright"; import { bech32 } from "bech32"; import { functionWaitedAssert } from "./waitedLoop"; @@ -55,3 +55,33 @@ export async function skipIfMainnet() { test.skip(); } } + +export async function skipIfTemporyWalletIsNotAvailable(fileName: string) { + const wallets = (await getFile(fileName)) || []; + if (wallets.length === 0) { + await allure.description( + `Temporary wallet file "${fileName}" is not available or contains insufficient wallet. Please fund the faucet wallet and run the test again.` + ); + test.skip(); + } +} + +export async function skipIfBalanceIsInsufficient(limit = 10) { + const balance = await getWalletBalance(environments.faucet.address); + if (balance <= limit) { + await allure.description("Not enough balance to perform this action."); + test.skip(); + } +} + +export async function getWalletBalance(address: string) { + let balance: number = 0; + await functionWaitedAssert( + async () => { + balance = await kuberService.getBalance(address); + }, + { message: "get balance" } + ); + + return balance; +} diff --git a/tests/govtool-frontend/playwright/lib/helpers/crypto.ts b/tests/govtool-frontend/playwright/lib/helpers/crypto.ts index 1ee98017f..c221c747e 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/crypto.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/crypto.ts @@ -2,6 +2,7 @@ import environments from "../constants/environments"; import { ed25519 as ed } from "@noble/curves/ed25519"; import { bech32 } from "bech32"; import * as blake from "blakejs"; +import { rewardAddressBech32, rewardAddressRawBytes } from "./shellyWallet"; const KEY_HASH_LENGTH = 28; const ADDR_LENGTH = KEY_HASH_LENGTH * 2 + 1; @@ -117,22 +118,13 @@ export class ShelleyWallet { concatenatedArray1.set(this.stakeKey.pkh, KEY_HASH_LENGTH + 1); return concatenatedArray1; } + rewardAddressRawBytes(network: number) { - const rewardAccountPrefix = 0xe0; - const header = network | rewardAccountPrefix; - const result = new Uint8Array(KEY_HASH_LENGTH + 1); - result[0] = header; - result.set(this.stakeKey.pkh, 1); - return result; + return rewardAddressRawBytes(network, this.stakeKey.json().pkh); } rewardAddressBech32(networkId: number): string { - const prefix = networkId == 0 ? "stake" : "stake_test"; - return bech32.encode( - prefix, - bech32.toWords(Buffer.from(this.rewardAddressRawBytes(networkId))), - 200 - ); + return rewardAddressBech32(networkId, this.stakeKey.json().pkh); } dRepIdBech32() { diff --git a/tests/govtool-frontend/playwright/lib/helpers/dRep.ts b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts index 40d9e694d..8572e217f 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/dRep.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts @@ -4,6 +4,10 @@ import { IDRep } from "@types"; import { bech32 } from "bech32"; import * as crypto from "crypto"; import { functionWaitedAssert } from "./waitedLoop"; +import { invalid as mockInvalid, valid as mockValid } from "@mock/index"; +import { faker } from "@faker-js/faker"; +import { ShelleyWallet } from "./crypto"; +import environments from "@constants/environments"; export async function fetchFirstActiveDRepDetails(page: Page) { let dRepGivenName: string; @@ -126,3 +130,49 @@ export function convertDRep( cip129DRep = drepIdFromHex("drep", cip129DrepHex); return { cip129: cip129DRep, cip105: cip105DRep }; } + +export async function generateValidDRepInfo() { + return { + name: mockValid.name(), + objectives: faker.lorem.paragraph(2), + motivations: faker.lorem.paragraph(2), + qualifications: faker.lorem.paragraph(2), + paymentAddress: (await ShelleyWallet.generate()).addressBech32( + environments.networkId + ), + linksReferenceLinks: [ + { + url: faker.internet.url(), + description: faker.internet.displayName(), + }, + ], + identityReferenceLinks: [ + { + url: faker.internet.url(), + description: faker.internet.displayName(), + }, + ], + }; +} + +export function generateInvalidDRepInfo() { + return { + name: mockInvalid.name(), + objectives: faker.lorem.paragraph(40), + motivations: faker.lorem.paragraph(40), + qualifications: faker.lorem.paragraph(40), + paymentAddress: faker.string.alphanumeric(45), + linksReferenceLinks: [ + { + url: mockInvalid.url(), + description: faker.lorem.paragraph(40), + }, + ], + identityReferenceLinks: [ + { + url: mockInvalid.url(), + description: faker.lorem.paragraph(40), + }, + ], + }; +} diff --git a/tests/govtool-frontend/playwright/lib/helpers/file.ts b/tests/govtool-frontend/playwright/lib/helpers/file.ts index 25fa3239b..d8145b0a4 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/file.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/file.ts @@ -1,12 +1,13 @@ -import { readFile, writeFile } from "fs"; +import { readFile, rm, writeFile } from "fs"; const path = require("path"); -const baseFilePath = path.resolve(__dirname, "../_mock"); +const mockFolderPath = path.resolve(__dirname, "../_mock"); +const basePath = path.join(__dirname, "../.."); export async function createFile(fileName: string, data?: any) { await new Promise((resolve, reject) => writeFile( - `${baseFilePath}/${fileName}`, + `${mockFolderPath}/${fileName}`, JSON.stringify(data, null, 2), (err) => { if (err) { @@ -21,7 +22,7 @@ export async function createFile(fileName: string, data?: any) { export async function getFile(fileName: string): Promise { const data: string = await new Promise((resolve, reject) => - readFile(`${baseFilePath}/${fileName}`, "utf8", (err, data) => { + readFile(`${mockFolderPath}/${fileName}`, "utf8", (err, data) => { if (err) { if (err.code === "ENOENT") { resolve(undefined); @@ -35,3 +36,35 @@ export async function getFile(fileName: string): Promise { ); return data ? JSON.parse(data) : undefined; } + +export async function deleteFile(fileName: string): Promise { + await new Promise((resolve, reject) => + rm(`${mockFolderPath}/${fileName}`, (err) => { + if (err) { + if (err.code === "ENOENT") { + resolve(); + } else { + reject(err); + } + } else { + resolve(); + } + }) + ); +} + +export async function deleteFolder(folderName: string): Promise { + await new Promise((resolve, reject) => + rm(`${basePath}/${folderName}`, { recursive: true, force: true }, (err) => { + if (err) { + if (err.code === "ENOENT") { + resolve(); + } else { + reject(err); + } + } else { + resolve(); + } + }) + ); +} diff --git a/tests/govtool-frontend/playwright/lib/helpers/index.ts b/tests/govtool-frontend/playwright/lib/helpers/index.ts index 1d78b1277..3b5b658eb 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/index.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/index.ts @@ -1,3 +1,4 @@ +import environments from "@constants/environments"; export const parseVotingPowerAndPercentage = ( combinedString: string ): { votingPower: string; percentage: string } => { @@ -14,3 +15,15 @@ export const parseVotingPowerAndPercentage = ( percentage, }; }; + +export const getWalletConfigForFaucet = () => { + return { + payment: { + private: environments.faucet.payment.private || "", + }, + stake: { + pkh: environments.faucet.stake.pkh || "", + }, + address: environments.faucet.address || "", + }; +}; diff --git a/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts b/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts index 4bf66bd48..aa8001906 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts @@ -2,6 +2,7 @@ import { bech32 } from "bech32"; import { blake2bHex } from "blakejs"; import convertBufferToHex from "./convertBufferToHex"; import { ShelleyWallet } from "./crypto"; +const KEY_HASH_LENGTH = 28; export default function extractDRepFromWallet(wallet: ShelleyWallet) { const dRepPubKey = convertBufferToHex(wallet.dRepKey.public); @@ -13,6 +14,28 @@ export default function extractDRepFromWallet(wallet: ShelleyWallet) { return dRepIdBech32; } +export function rewardAddressRawBytes(network: number, stakePkh: string) { + const stakePkhBytes = Uint8Array.from(Buffer.from(stakePkh, "hex")); + const rewardAccountPrefix = 0xe0; + const header = network | rewardAccountPrefix; + const result = new Uint8Array(KEY_HASH_LENGTH + 1); + result[0] = header; + result.set(stakePkhBytes, 1); + return result; +} + +export function rewardAddressBech32( + networkId: number, + stakePkh: string +): string { + const prefix = networkId == 0 ? "stake" : "stake_test"; + return bech32.encode( + prefix, + bech32.toWords(Buffer.from(rewardAddressRawBytes(networkId, stakePkh))), + 200 + ); +} + export async function generateWallets(num: number) { return await Promise.all( Array.from({ length: num }, () => diff --git a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts index cd781b1ec..babcc07bb 100644 --- a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts @@ -56,7 +56,10 @@ export default class BudgetDiscussionDetailsPage { readonly proposalContractingContent = this.page.getByTestId( "proposal-contracting" ); - readonly costingAmountContent = this.page.getByTestId("consting-amount"); // BUG typo + readonly proposalContractingOtherContent = this.page.getByTestId( + "other-contract-description" + ); + readonly costingAmountContent = this.page.getByTestId("costing-amount"); readonly costingConversionRateContent = this.page.getByTestId( "costing-conversion-rate" ); @@ -64,7 +67,7 @@ export default class BudgetDiscussionDetailsPage { "costing-preferred-currency" ); readonly costingPreferedCurrencyAmountContent = this.page.getByTestId( - "costing-prefereed-currency-amount" + "costing-preferred-currency-amount" ); readonly costBreakdownContent = this.page.getByTestId("cost-breakdown"); readonly includeAsAuditorContent = @@ -192,6 +195,12 @@ export default class BudgetDiscussionDetailsPage { budgetProposal.proposalDetails.contracting ); + if (budgetProposal.proposalDetails.contracting === "Other") { + await expect(this.proposalContractingOtherContent).toHaveText( + budgetProposal.proposalDetails.otherDescription + ); + } + // costing validation await expect(this.costingAmountContent).toHaveText( `₳ ${formatWithThousandSeparator(budgetProposal.costing.adaAmount)}` diff --git a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionSubmissionPage.ts index 66a0a20c7..b37520f54 100644 --- a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionSubmissionPage.ts @@ -228,6 +228,9 @@ export default class BudgetDiscussionSubmissionPage { readonly contractingContent = this.page.getByTestId( "contracting-type-name-content" ); + readonly contractingOtherContent = this.page.getByTestId( + "other-contract-description" + ); // costing readonly adaAmountContent = this.page.getByTestId("ada-amount-content"); @@ -759,6 +762,12 @@ export default class BudgetDiscussionSubmissionPage { proposalInformations.proposalDetails.contracting ); + if (proposalInformations.proposalDetails.contracting === "Other") { + await expect(this.contractingOtherContent).toHaveText( + proposalInformations.proposalDetails.otherDescription + ); + } + // costing await expect(this.adaAmountContent).toHaveText( `₳ ${formatWithThousandSeparator(proposalInformations.costing.adaAmount)}` diff --git a/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts index 878d71b67..dd94a1c6b 100644 --- a/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts @@ -1,7 +1,14 @@ import environments from "@constants/environments"; import { formatWithThousandSeparator } from "@helpers/adaFormat"; -import { Page, Response } from "@playwright/test"; -import { outcomeProposal, VoterType } from "@types"; +import { Browser, expect, Page, Response } from "@playwright/test"; +import { outcomeProposal, outcomeType } from "@types"; +import OutComesPage from "./outcomesPage"; +import { + areCCVoteTotalsDisplayed, + areDRepVoteTotalsDisplayed, + areSPOVoteTotalsDisplayed, +} from "@helpers/featureFlag"; +import { parseVotingPowerAndPercentage } from "@helpers/index"; export default class OutcomeDetailsPage { readonly dRepYesVotes = this.page.getByTestId("DReps-yes-votes-submitted"); @@ -81,4 +88,226 @@ export default class OutcomeDetailsPage { sPosNoConfidence, }; } + + async shouldDisplayCorrectVotingResults( + browser: Browser, + isLoggedIn = false + ) { + await Promise.all( + Object.keys(outcomeType).map(async (filterKey) => { + const outcomePage = new OutComesPage(this.page); + const { + govActionDetailsPage, + metricsResponsePromise, + outcomeResponsePromise, + } = await outcomePage.navigateToFilteredProposalDetail( + browser, + filterKey, + isLoggedIn + ); + + const outcomeResponse = await outcomeResponsePromise; + const proposalToCheck = (await outcomeResponse.json())[0]; + + const metricsResponse = await metricsResponsePromise; + + const { autoAbstain, noConfidence, sPosAutoAbstain, sPosNoConfidence } = + await govActionDetailsPage.getSposAndDRepAbstainNoConfidence( + metricsResponse + ); + + const currentPageUrl = govActionDetailsPage.currentPage.url(); + + // check dRep votes + if (await areDRepVoteTotalsDisplayed(proposalToCheck)) { + await govActionDetailsPage.dRepExpandButton.click(); + + await expect( + govActionDetailsPage.dRepResultData.getByRole("row", { + name: "Yes", + }), + { + message: `DRep "Yes" voting power checked for ${currentPageUrl}`, + } + ).toHaveText( + `Yes${formatWithThousandSeparator(proposalToCheck.yes_votes, false)}`, + { + timeout: 60_000, + } + ); //BUG missing testIds + + await expect( + govActionDetailsPage.dRepResultData.getByRole("row", { + name: "Auto-Abstain", + }), + { + message: `DRep "Auto-Abstain" voting power checked for ${currentPageUrl}`, + } + ).toHaveText(`Auto-Abstain${autoAbstain}`); //BUG missing testIds + await expect( + govActionDetailsPage.dRepResultData.getByRole("row", { + name: "No Confidence", + }), + { + message: `DRep "No Confidence" voting power checked for ${currentPageUrl}`, + } + ).toHaveText(`No Confidence${noConfidence}`); //BUG missing testIds + await expect( + govActionDetailsPage.dRepResultData.getByRole("row", { + name: "Explicit", + }), + { + message: `DRep "Explicit" voting power checked for ${currentPageUrl}`, + } + ).toHaveText( + `Explicit${formatWithThousandSeparator(proposalToCheck.abstain_votes, false)}` + ); + + await expect( + govActionDetailsPage.dRepResultData + .getByRole("row", { + name: "No", + }) + .first(), + { + message: `DRep "No" voting power checked for ${currentPageUrl}`, + } + ).toHaveText( + `No${formatWithThousandSeparator(proposalToCheck.no_votes, false)}` + ); //BUG missing testIds + } + + // check sPos votes + if (await areSPOVoteTotalsDisplayed(proposalToCheck)) { + await govActionDetailsPage.sPosExpandButton.click(); + const totalSposNoVotes = + filterKey === "NoConfidence" + ? proposalToCheck.pool_no_votes + : parseInt(sPosNoConfidence.replace(/,/g, "")) * 1000000 + + parseInt(proposalToCheck.pool_no_votes); + + const totalSposYesVotesForNoConfidence = + parseInt(sPosNoConfidence.replace(/,/g, "")) * 1000000 + + parseInt(proposalToCheck.pool_yes_votes); + + const totalSposYesVotes = + filterKey === "NoConfidence" + ? totalSposYesVotesForNoConfidence + : proposalToCheck.pool_yes_votes; + await expect( + govActionDetailsPage.sPosResultData.getByRole("row", { + name: "Yes", + }), + { + message: `SPos "Yes" voting power checked for ${currentPageUrl}`, + } + ).toHaveText( + `Yes${formatWithThousandSeparator(totalSposYesVotes, false)}`, + { + timeout: 60_000, + } + ); //BUG missing testIds + + await expect( + govActionDetailsPage.sPosResultData.getByRole("row", { + name: "Auto-Abstain", + }), + { + message: `SPos "Auto-Abstain" voting power checked for ${currentPageUrl}`, + } + ).toHaveText(`Auto-Abstain${sPosAutoAbstain}`); //BUG missing testIds + await expect( + govActionDetailsPage.sPosResultData.getByRole("row", { + name: "No Confidence", + }), + { + message: `SPos "No Confidence" voting power checked for ${currentPageUrl}`, + } + ).toHaveText(`No Confidence${sPosNoConfidence}`); //BUG missing testIds + await expect( + govActionDetailsPage.sPosResultData.getByRole("row", { + name: "Explicit", + }), + { + message: `SPos "Explicit" voting power checked for ${currentPageUrl}`, + } + ).toHaveText( + `Explicit${formatWithThousandSeparator(proposalToCheck.pool_abstain_votes, false)}` + ); //BUG missing testIds + await expect( + govActionDetailsPage.sPosResultData + .getByRole("row", { + name: "No", + }) + .first(), + { + message: `SPos "No" voting power checked for ${currentPageUrl}`, + } + ).toHaveText( + `No${formatWithThousandSeparator(totalSposNoVotes, false)}` + ); //BUG missing testIds + } + + // check ccCommittee votes + if (areCCVoteTotalsDisplayed(proposalToCheck)) { + const ccYesVoteSubmittedText = + await govActionDetailsPage.ccCommitteeYesVotes.textContent(); + + const { percentage: yesPercentage } = parseVotingPowerAndPercentage( + ccYesVoteSubmittedText + ); + + await expect(govActionDetailsPage.ccCommitteeYesVotes, { + message: `CC "Yes" vote count checked for ${currentPageUrl}`, + }).toHaveText(`${proposalToCheck.cc_yes_votes} - ${yesPercentage}`); + await expect( + govActionDetailsPage.cCResultData.getByRole("row", { + name: "Abstain Votes", + }), + { + message: `CC "Abstain" vote count checked for ${currentPageUrl}`, + } + ).toHaveText(`Abstain Votes${proposalToCheck.pool_abstain_votes}`); //BUG missing testIds + + const noPercentage = 100 - parseFloat(yesPercentage.replace("%", "")); + await expect(govActionDetailsPage.ccCommitteeNoVotes, { + message: `CC "No" vote count checked for ${currentPageUrl}`, + }).toHaveText( + `${proposalToCheck.cc_no_votes} - ${noPercentage.toFixed(2)}%` + ); + } + }) + ); + } + + async verifyInvalidOutcomeMetadata({ + outcomeResponse, + type, + url, + hash, + }: { + outcomeResponse: outcomeProposal; + type: string; + url: string; + hash: string; + }) { + await this.page.route(/.*\/governance-actions\/[a-f0-9]{64}\?.*/, (route) => + route.fulfill({ body: JSON.stringify([outcomeResponse]) }) + ); + + const outcomePage = new OutComesPage(this.page); + await outcomePage.goto(); + await outcomePage.viewFirstOutcomes(); + const outcomeTitle = await outcomePage.title.textContent(); + + await expect( + outcomePage.title, + outcomeTitle.toLowerCase() !== type.toLowerCase() && + `The URL "${url}" and hash "${hash}" do not match the expected properties for type "${type}".` + ).toHaveText(type, { + ignoreCase: true, + timeout: 60_000, + }); + await expect(outcomePage.metadataErrorLearnMoreBtn).toBeVisible(); + } } diff --git a/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts b/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts index 0d0d3e0f8..031dfa5e9 100644 --- a/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts @@ -2,9 +2,24 @@ import environments from "@constants/environments"; import { outcomeStatusType } from "@constants/index"; import { toCamelCase } from "@helpers/string"; import { functionWaitedAssert, waitedLoop } from "@helpers/waitedLoop"; -import { expect, Locator, Page } from "@playwright/test"; -import { outcomeProposal, outcomeType } from "@types"; +import { Browser, expect, Locator, Page } from "@playwright/test"; +import { outcomeMetadata, outcomeProposal, outcomeType } from "@types"; import OutcomeDetailsPage from "./outcomeDetailsPage"; +import { isMobile } from "@helpers/mobile"; +import extractExpiryDateFromText from "@helpers/extractExpiryDateFromText"; +import { createNewPageWithWallet, injectLogger } from "@helpers/page"; +import { createTempUserAuth } from "@datafactory/createAuth"; +import { user01Wallet } from "@constants/staticWallets"; +import { user01AuthFile } from "@constants/auth"; + +const status = ["Expired", "Ratified", "Enacted", "Live"]; + +enum SortOption { + SoonToExpire = "Soon to expire", + NewestFirst = "Newest first", + OldestFirst = "Oldest first", + HighestAmountYesVote = "Highest amount of yes votes", +} export default class OutComesPage { // Buttons @@ -236,4 +251,321 @@ export default class OutComesPage { }); return outcomeStatus.some((status) => filters.includes(status)); } + + async shouldAccessPage() { + await this.page.goto("/"); + + if (isMobile(this.page)) { + await this.page.getByTestId("open-drawer-button").click(); + } + await this.page.getByTestId("governance-actions-outcomes-link").click(); + + await expect(this.page.getByText(/outcomes/i)).toHaveCount(2); + } + + async filterOutcomes() { + await this.filterBtn.click(); + const filterOptionNames = Object.values(outcomeType); + + // proposal type filter + await this.applyAndValidateFilters( + filterOptionNames, + this._validateFiltersInOutcomeCard + ); + + // proposal status filter + await this.applyAndValidateFilters( + status, + this._validateStatusFiltersInOutcomeCard + ); + } + + async sortOutcomes() { + await this.sortBtn.click(); + + await this.sortAndValidate( + SortOption.NewestFirst, + (p1, p2) => p1.expiry_date >= p2.time + ); + + await this.sortAndValidate( + SortOption.OldestFirst, + (p1, p2) => p1.expiry_date <= p2.expiry_date + ); + + await this.sortAndValidate( + SortOption.HighestAmountYesVote, + (p1, p2) => parseInt(p1.yes_votes) >= parseInt(p2.yes_votes) + ); + } + + async filterAndSortOutcomes() { + const filterOptionKeys = Object.keys(outcomeType); + const filterOptionNames = Object.values(outcomeType); + + const choice = Math.floor(Math.random() * filterOptionKeys.length); + await this.goto({ filter: filterOptionKeys[choice] }); + await this.sortBtn.click(); + + await this.sortAndValidate( + SortOption.OldestFirst, + (p1, p2) => p1.expiry_date <= p2.expiry_date + ); + + await this.validateFilters( + [filterOptionNames[choice]], + this._validateFiltersInOutcomeCard + ); + } + + async verifyAllOutcomesAreExpired() { + const proposalCards = await this.getAllOutcomes(); + + for (const proposalCard of proposalCards) { + const expiryDateEl = proposalCard.locator( + '[data-testid$="-Expired-date"]' + ); + const expiryDateTxt = await expiryDateEl.innerText(); + const expiryDate = extractExpiryDateFromText(expiryDateTxt); + const today = new Date(); + expect(today >= expiryDate).toBeTruthy(); + } + } + + async VerifyLoadMoreOutcomes() { + const responsePromise = this.page.waitForResponse((response) => + response + .url() + .includes(`governance-actions?search=&filters=&sort=newestFirst&page=2`) + ); + await this.goto(); + + let governanceActionIdsBefore: String[]; + let governanceActionIdsAfter: String[]; + + await functionWaitedAssert( + async () => { + governanceActionIdsBefore = + await this.getAllListedCIP105GovernanceIds(); + await this.showMoreBtn.click(); + }, + { message: "Show more button not visible" } + ); + + const response = await responsePromise; + const governanceActionListAfter = await response.json(); + + await functionWaitedAssert( + async () => { + governanceActionIdsAfter = await this.getAllListedCIP105GovernanceIds(); + expect(governanceActionIdsAfter.length).toBeGreaterThan( + governanceActionIdsBefore.length + ); + }, + { message: "Outcomes not loaded after clicking show more" } + ); + + if (governanceActionListAfter.length >= governanceActionIdsBefore.length) { + await expect(this.showMoreBtn).toBeVisible(); + expect(true).toBeTruthy(); + } else { + await expect(this.showMoreBtn).not.toBeVisible(); + } + } + + async fetchOutcomeIdAndTitleFromNetwork( + governanceActionId: string, + governanceActionTitle: string + ) { + let updatedGovernanceActionId = governanceActionId; + let updatedGovernanceActionTitle = governanceActionTitle; + await this.page.route( + "**/governance-actions?search=&filters=&sort=**", + async (route) => { + const response = await route.fetch(); + const data: outcomeProposal[] = await response.json(); + if (!governanceActionId) { + if (data.length > 0) { + const randomIndexForId = Math.floor(Math.random() * data.length); + updatedGovernanceActionId = + data[randomIndexForId].tx_hash + + "#" + + data[randomIndexForId].index; + } + } + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(data), + }); + } + ); + + await this.page.route( + "**/governance-actions/metadata?**", + async (route) => { + try { + const response = await route.fetch(); + if (response.status() !== 200) { + await route.continue(); + return; + } + const data: outcomeMetadata = await response.json(); + if (!governanceActionTitle && data.data.title != null) { + updatedGovernanceActionTitle = data.data.title; + } + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(data), + }); + } catch (error) { + return; + } + } + ); + + const responsePromise = this.page.waitForResponse( + "**/governance-actions?search=&filters=&sort=**" + ); + const metadataResponsePromise = this.page.waitForResponse( + "**/governance-actions/metadata?**" + ); + + await this.goto(); + await responsePromise; + await metadataResponsePromise; + return { + governanceActionId: updatedGovernanceActionId, + governanceActionTitle: updatedGovernanceActionTitle, + }; + } + + async searchOutcomesById(governanceActionId: string) { + await this.searchInput.fill(governanceActionId); + await expect( + this.page.getByRole("progressbar").getByRole("img") + ).toBeVisible(); + + await functionWaitedAssert( + async () => { + const idSearchOutcomeCards = await this.getAllOutcomes(); + expect(idSearchOutcomeCards.length, { + message: + idSearchOutcomeCards.length == 0 && "No governance actions found", + }).toBeGreaterThan(0); + for (const outcomeCard of idSearchOutcomeCards) { + const id = await outcomeCard + .locator('[data-testid$="-CIP-105-id"]') + .textContent(); + expect(id.replace(/^.*ID/, "")).toContain(governanceActionId); + } + }, + { name: "search by id" } + ); + } + + async searchOutcomesByTitle(governanceActionTitle: string) { + await this.searchInput.fill(governanceActionTitle); + await expect( + this.page.getByRole("progressbar").getByRole("img") + ).toBeVisible(); + + await functionWaitedAssert( + async () => { + const titleSearchOutcomeCards = await this.getAllOutcomes(); + expect(titleSearchOutcomeCards.length, { + message: + titleSearchOutcomeCards.length == 0 && + "No governance actions found", + }).toBeGreaterThan(0); + for (const outcomeCard of titleSearchOutcomeCards) { + const title = await outcomeCard + .locator('[data-testid$="-card-title"]') + .textContent(); + expect(title.toLowerCase()).toContain( + governanceActionTitle.toLowerCase() + ); + } + }, + { name: "search by title" } + ); + } + + async shouldCopyGovernanceActionId(governanceActionId: string) { + await this.searchInput.fill(governanceActionId); + + await this.page + .getByTestId(`${governanceActionId}-CIP-105-id`) + .getByTestId("copy-button") + .click(); + await expect(this.page.getByText("Copied to clipboard")).toBeVisible({ + timeout: 60_000, + }); + const copiedTextDRepDirectory = await this.page.evaluate(() => + navigator.clipboard.readText() + ); + expect(copiedTextDRepDirectory).toEqual(governanceActionId); + } + + async navigateToFilteredProposalDetail( + browser: Browser, + filterKey: string, + isLoggedIn: boolean + ) { + let page: Page; + if (!isLoggedIn) { + page = await browser.newPage(); + } else { + page = await createNewPageWithWallet(browser, { + storageState: user01AuthFile, + wallet: user01Wallet, + }); + } + injectLogger(page); + + const outcomeListResponsePromise = page.waitForResponse( + (response) => + response + .url() + .includes(`governance-actions?search=&filters=${filterKey}`), + { timeout: 60_000 } + ); + + const metricsResponsePromise = page.waitForResponse( + (response) => response.url().includes(`/misc/network/metrics?epoch`), + { timeout: 60_000 } + ); + + const outcomePage = new OutComesPage(page); + await outcomePage.goto({ filter: filterKey }); + + const outcomeListResponse = await outcomeListResponsePromise; + const proposals = await outcomeListResponse.json(); + + expect( + proposals.length, + proposals.length == 0 && "No proposals found!" + ).toBeGreaterThan(0); + + const { index: governanceActionIndex, tx_hash: governanceTransactionHash } = + proposals[0]; + + const outcomeResponsePromise = page.waitForResponse( + (response) => + response + .url() + .includes( + `governance-actions/${governanceTransactionHash}?index=${governanceActionIndex}` + ), + { timeout: 60_000 } + ); + + const govActionDetailsPage = await outcomePage.viewFirstOutcomes(); + return { + govActionDetailsPage, + outcomeResponsePromise, + metricsResponsePromise, + }; + } } diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index 9b991580a..0c3d7cc09 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -544,22 +544,18 @@ export default class ProposalSubmissionPage { } async createProposal( - wallet: StaticWallet, + receivingAddress: string, proposalType: ProposalType = Object.values(ProposalType)[ Math.floor(Math.random() * Object.values(ProposalType).length) ] ): Promise { await this.addLinkBtn.click(); - const receivingAddr = ShelleyWallet.fromJson(wallet).rewardAddressBech32( - environments.networkId - ); - const proposalRequest: ProposalCreateRequest = await this.generateValidProposalFormFields({ proposalType: (await isBootStrapingPhase()) ? ProposalType.info : proposalType, - receivingAddress: receivingAddr, + receivingAddress, }); await this.fillupForm(proposalRequest); await this.continueBtn.click(); diff --git a/tests/govtool-frontend/playwright/lib/services/kuberService.ts b/tests/govtool-frontend/playwright/lib/services/kuberService.ts index 9047faecb..206a348de 100644 --- a/tests/govtool-frontend/playwright/lib/services/kuberService.ts +++ b/tests/govtool-frontend/playwright/lib/services/kuberService.ts @@ -1,4 +1,3 @@ -import { faucetWallet } from "@constants/staticWallets"; import { KuberValue, ProtocolParams, @@ -12,7 +11,7 @@ import fetch, { BodyInit, RequestInit } from "node-fetch"; import { cborxEncoder } from "@helpers/encodeDecode"; import { Logger } from "@helpers/logger"; import { blockfrostSubmitTransaction } from "@services/blockfrostService"; -import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; +import { getWalletConfigForFaucet } from "@helpers/index"; type CertificateType = "registerstake" | "registerdrep" | "deregisterdrep"; @@ -139,8 +138,8 @@ const kuberService = { // register stake and outputs 20A initializeWallets: ( wallets: StaticWallet[], - faucetAddress: string = faucetWallet.address, - faucetStakeKey: string = faucetWallet.payment.private + faucetAddress: string = getWalletConfigForFaucet().address, + faucetStakeKey: string = getWalletConfigForFaucet().payment.private ) => { const kuber = new Kuber(faucetAddress, faucetStakeKey); const outputs = []; @@ -168,8 +167,8 @@ const kuberService = { }, mergeUtXos: (wallets: StaticWallet[]) => { const kuber = new Kuber( - proposalFaucetWallet.address, - proposalFaucetWallet.payment.private + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private ); const selections = wallets.map((wallet) => ({ type: "PaymentSigningKeyShelley_ed25519", @@ -181,12 +180,15 @@ const kuberService = { return kuber.signAndSubmitTx({ inputs, selections, - changeAddress: proposalFaucetWallet.address, + changeAddress: getWalletConfigForFaucet().address, }); }, transferADA: (receiverAddressList: string[], ADA = 20) => { - const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); + const kuber = new Kuber( + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private + ); const req = { outputs: receiverAddressList.map((addr) => { return { @@ -200,8 +202,8 @@ const kuberService = { multipleTransferADA: ( outputs: { address: string; value: string | number }[], - addr = faucetWallet.address, - signingKey = faucetWallet.payment.private + addr = getWalletConfigForFaucet().address, + signingKey = getWalletConfigForFaucet().payment.private ) => { const kuber = new Kuber(addr, signingKey); const req = { @@ -212,8 +214,8 @@ const kuberService = { multipleDRepRegistration: (metadataAndWallets: WalletAndAnchorType[]) => { const kuber = new Kuber( - proposalFaucetWallet.address, - proposalFaucetWallet.payment.private + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private ); const req = { certificates: metadataAndWallets.map((metadataAndWallet) => @@ -239,7 +241,10 @@ const kuberService = { pkh: string, metadata: WalletAndAnchorType ) => { - const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); + const kuber = new Kuber( + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private + ); const req = { certificates: [Kuber.generateCert("registerdrep", pkh, metadata)], @@ -276,7 +281,10 @@ const kuberService = { }, multipleDRepDeRegistration: (wallets: StaticWallet[]) => { - const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); + const kuber = new Kuber( + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private + ); const req = { certificates: wallets.map((wallet) => Kuber.generateCert("deregisterdrep", wallet.stake.pkh) @@ -288,7 +296,7 @@ const kuberService = { cborHex: `5820${wallet.stake.private}`, }; }), - inputs: faucetWallet.address, + inputs: getWalletConfigForFaucet().address, }; return kuber.signAndSubmitTx(req); }, @@ -352,7 +360,10 @@ const kuberService = { }, createGovAction(proposalsCount = 2) { - const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); + const kuber = new Kuber( + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private + ); const infoProposal = { deposit: 1000000000, refundAccount: { @@ -429,7 +440,10 @@ const kuberService = { stakePrivKeys: string[], stakePkhs: string[] ): Promise { - const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); + const kuber = new Kuber( + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private + ); const selections = stakePrivKeys.map((key) => { return { type: "PaymentSigningKeyShelley_ed25519", diff --git a/tests/govtool-frontend/playwright/lock_logs.txt b/tests/govtool-frontend/playwright/lock_logs.txt new file mode 100644 index 000000000..84773e7f4 --- /dev/null +++ b/tests/govtool-frontend/playwright/lock_logs.txt @@ -0,0 +1,525 @@ +[5/5/2025, 11:58:55 AM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 11:58:55 AM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 11:58:56 AM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 11:59:22 AM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 11:59:22 AM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:01:03 PM] Task completed for:undefined +[5/5/2025, 12:01:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:01:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:01:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:01:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:01:38 PM] Task completed for:undefined +[5/5/2025, 12:01:38 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:01:38 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:01:54 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:01:54 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:01:55 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:02:46 PM] Task completed for:undefined +[5/5/2025, 12:02:46 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:02:46 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:02:46 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:02:46 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:02:47 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:02:50 PM] Task completed for:undefined +[5/5/2025, 12:02:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:02:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:02:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:02:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:02:53 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:02:53 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:02:53 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:02:53 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:02:54 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:02:54 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:02:54 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:02:54 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:04:05 PM] Task completed for:undefined +[5/5/2025, 12:04:05 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:04:05 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:04:05 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:04:05 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:05:01 PM] Task completed for:undefined +[5/5/2025, 12:05:01 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:05:01 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:05:18 PM] Initiator: tempWallets + ---------------------> waiting lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:05:18 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:05:40 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:05:40 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:05:40 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:05:40 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:06:17 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:06:17 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:06:17 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:06:17 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:08:13 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:08:13 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:08:39 PM] Task completed for:undefined +[5/5/2025, 12:08:39 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:08:39 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:08:43 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:08:43 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:08:44 PM] Task failure: +{"error":"{\"status\":400}"} +[5/5/2025, 12:08:44 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:08:44 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:08:47 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:08:47 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:09:01 PM] Task completed for:undefined +[5/5/2025, 12:09:01 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:09:01 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:19:48 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:19:48 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:19:49 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:20:02 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:20:02 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:20:21 PM] Task completed for:undefined +[5/5/2025, 12:20:21 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:20:21 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:20:21 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:20:21 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:20:35 PM] Task completed for:undefined +[5/5/2025, 12:20:35 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:20:35 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:20:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:20:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:20:51 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:20:55 PM] Task completed for:undefined +[5/5/2025, 12:20:55 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:20:55 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:20:55 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:20:55 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:20:56 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:21:20 PM] Task completed for:undefined +[5/5/2025, 12:21:20 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:21:20 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:21:20 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:21:20 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:22:27 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:22:27 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:27:30 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:27:30 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:28:49 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:28:49 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:29:04 PM] Task completed for:undefined +[5/5/2025, 12:29:04 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:29:04 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:41:47 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:41:47 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:41:47 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:41:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:41:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:42:11 PM] Task completed for:undefined +[5/5/2025, 12:42:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:42:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:42:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:42:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:42:25 PM] Task completed for:undefined +[5/5/2025, 12:42:25 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:42:25 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:42:49 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:42:49 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:42:50 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:42:57 PM] Task completed for:undefined +[5/5/2025, 12:42:57 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:42:57 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:42:57 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:42:57 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:42:58 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd + ---------------------> waiting lock for:undefined +[5/5/2025, 12:43:11 PM] Task completed for:undefined +[5/5/2025, 12:43:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:43:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:43:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:43:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:44:29 PM] Task completed for:undefined +[5/5/2025, 12:44:29 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:44:29 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:44:29 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:44:29 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:44:42 PM] Task completed for:undefined +[5/5/2025, 12:44:42 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:44:42 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:45:12 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:45:18 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:45:18 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:45:18 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:45:18 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:45:19 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:45:19 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:45:19 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:45:19 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:46:43 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:46:44 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:46:44 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:46:44 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:46:44 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:47:07 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:47:07 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:47:07 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:47:07 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:47:41 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:47:41 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:47:41 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:47:41 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:48:38 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:48:38 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:48:38 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:48:38 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:48:42 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:48:42 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:48:42 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:48:42 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:48:59 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 12:48:59 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 12:48:59 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 12:48:59 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 12:52:05 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:52:05 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:53:02 PM] Task completed for:undefined +[5/5/2025, 12:53:02 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:53:02 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:53:06 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:53:06 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:53:07 PM] Task failure: +{"error":"{\"status\":400}"} +[5/5/2025, 12:53:07 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:53:07 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 12:53:10 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 12:53:10 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 12:53:23 PM] Task completed for:undefined +[5/5/2025, 12:53:23 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 12:53:23 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 1:31:04 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 1:31:04 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 1:32:31 PM] Task completed for:undefined +[5/5/2025, 1:32:31 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 1:32:31 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 1:32:32 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 1:32:32 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 1:33:03 PM] Task completed for:undefined +[5/5/2025, 1:33:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 1:33:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 1:33:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 1:33:03 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 1:33:11 PM] Task completed for:undefined +[5/5/2025, 1:33:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 1:33:11 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + +[5/5/2025, 1:33:40 PM] Initiator: tempWallets +---------------------> acquiring lock for:undefined +[5/5/2025, 1:33:40 PM] Initiator: tempWallets +---------------------> acquired lock for:undefined +[5/5/2025, 1:33:40 PM] Initiator: tempWallets +---------------------> releasing lock for:undefined +[5/5/2025, 1:33:40 PM] Initiator: tempWallets +---------------------> released lock for:undefined + +[5/5/2025, 1:35:20 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquiring lock for:undefined +[5/5/2025, 1:35:20 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> acquired lock for:undefined +[5/5/2025, 1:35:58 PM] Task completed for:undefined +[5/5/2025, 1:35:58 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> releasing lock for:undefined +[5/5/2025, 1:35:58 PM] Initiator: addr_test1qz3hqauh86zjg2c3wdqueava97mc4llr5pv5fvyfcgjc84jwvs0cxwl8qfkejj8ld2mp0ygjx9n2rjz0tr75w2ntxwjspd08dd +---------------------> released lock for:undefined + diff --git a/tests/govtool-frontend/playwright/package.json b/tests/govtool-frontend/playwright/package.json index 652504847..62bdac42d 100644 --- a/tests/govtool-frontend/playwright/package.json +++ b/tests/govtool-frontend/playwright/package.json @@ -23,10 +23,29 @@ "allure:generate": "npx allure generate ./allure-results --clean", "allure:open": "npx allure open ./allure-report", "allure:serve": "npx allure serve", - "test": "npx playwright test", + "test": "npx playwright test --ui", + "test:delegation-pillar": "npx playwright test delegation dRepRegistration editDRep --ui", + "test:voting-pillar": "npx playwright test proposalVisibility proposalFunctionality --ui", + "test:outcomes": "npx playwright test outcomes --ui", + "test:proposal-pillar": "npx playwright test proposalDiscussion proposalSubmission proposalBudget --ui", + "test:proposal-discussion": "npx playwright test proposalDiscussion proposalSubmission --ui", + "test:proposal-budget": "npx playwright test proposalBudget --ui", + "test:wallet-connect": "npx playwright test walletConnect --ui", + "test:usersnap": "npx playwright test userSnap.spec.ts --ui", + "test:misc": "npx playwright test miscellaneous --ui", + "test:headless": "npx playwright test", + "test:headless:delegation-pillar": "npx playwright test delegation dRepRegistration editDRep", + "test:headless:voting-pillar": "npx playwright test proposalVisibility proposalFunctionality", + "test:headless:outcomes": "npx playwright test outcomes", + "test:headless:proposal-pillar": "npx playwright test proposalDiscussion proposalSubmission proposalBudget", + "test:headless:proposal-discussion": "npx playwright test proposalDiscussion proposalSubmission", + "test:headless:proposal-budget": "npx playwright test proposalBudget", + "test:headless:wallet-connect": "npx playwright test walletConnect", + "test:headless:usersnap": "npx playwright test userSnap.spec.ts", + "test:headless:misc": "npx playwright test miscellaneous", "format": "prettier . --write", - "test:outcomes": "npx playwright test outcomes.spec.ts --ui", - "generate-wallets": "ts-node ./generate_wallets.ts 24" + "generate-wallets": "ts-node ./generate_wallets.ts 23", + "generate-faucet-wallet": "ts-node ./generate_faucet_wallet.ts" }, "dependencies": { "@cardanoapi/cardano-test-wallet": "^3.3.1", diff --git a/tests/govtool-frontend/playwright/playwright.config.ts b/tests/govtool-frontend/playwright/playwright.config.ts index 457c8d0a4..cc14955aa 100644 --- a/tests/govtool-frontend/playwright/playwright.config.ts +++ b/tests/govtool-frontend/playwright/playwright.config.ts @@ -44,27 +44,19 @@ export default defineConfig({ /* Configure projects for major browsers */ projects: [ { - name: "adaholder auth setup", - testMatch: "**/adaholder.auth.setup.ts", + name: "wallet bootstrap", + testMatch: "**/wallet.bootstrap.ts", + teardown: environments.ci && "cleanup faucet", }, { name: "user auth setup", testMatch: "**/user.auth.setup.ts", }, { - name: "faucet setup", - testMatch: "**/faucet.setup.ts", - teardown: environments.ci && "cleanup faucet", - }, - { - name: "dRep setup", - testMatch: "**/dRep.setup.ts", - dependencies: environments.ci ? ["faucet setup", "wallet bootstrap"] : [], - }, - { - name: "proposal budget dRep setup", - testMatch: "**/proposal-budget.dRep.setup.ts", - teardown: environments.ci && "cleanup faucet", + name: "adaholder auth setup", + testMatch: "**/adaholder.auth.setup.ts", + dependencies: environments.ci ? ["wallet bootstrap"] : [], + teardown: environments.ci && "cleanup artifacts", }, { name: "dRep auth setup", @@ -76,24 +68,25 @@ export default defineConfig({ testMatch: "**/proposal-discussion.auth.setup.ts", }, { - name: "proposal budget auth setup", + name: "budget proposal auth setup", testMatch: "**/proposal-budget.auth.setup.ts", + teardown: environments.ci && "cleanup faucet", }, { - name: "proposal setup", - testMatch: "**/proposal.setup.ts", - teardown: environments.ci && "cleanup faucet", + name: "dRep setup", + testMatch: "**/dRep.setup.ts", + dependencies: environments.ci ? ["wallet bootstrap"] : [], + teardown: environments.ci && "cleanup dRep", }, { - name: "wallet bootstrap", - testMatch: "**/wallet.bootstrap.ts", - dependencies: environments.ci ? ["faucet setup"] : [], + name: "budget proposal dRep setup", + testMatch: "**/proposal-budget.dRep.setup.ts", + teardown: environments.ci && "cleanup dRep", }, { - name: "transaction", - use: { ...devices["Desktop Chrome"] }, - testMatch: "**/*.tx.spec.ts", - dependencies: environments.ci ? ["adaholder auth setup", "wallet bootstrap"] : [], + name: "proposal setup", + testMatch: "**/proposal.setup.ts", + teardown: environments.ci && "cleanup faucet", }, { name: "proposal discussion", @@ -102,15 +95,17 @@ export default defineConfig({ dependencies: environments.ci ? ["proposal discussion auth setup"] : [], + teardown: environments.ci && "cleanup artifacts", }, { - name: "proposal budget", + name: "budget proposal", use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.pb.spec.ts", dependencies: environments.ci - ? ["proposal budget auth setup"] + ? ["budget proposal auth setup"] : [], testIgnore: ["**/*.dRep.pb.spec.ts"], + teardown: environments.ci && "cleanup artifacts", }, { name: "proposal submission", @@ -119,37 +114,39 @@ export default defineConfig({ dependencies: environments.ci ? ["proposal setup"] : [], + teardown: environments.ci && "cleanup artifacts", }, { name: "loggedin (desktop)", use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.loggedin.spec.ts", dependencies: environments.ci ? ["user auth setup"] : [], + teardown: environments.ci && "cleanup artifacts", }, { - name: "proposal budget dRep", + name: "budget proposal dRep", use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.dRep.pb.spec.ts", dependencies: environments.ci - ? ["proposal budget auth setup","proposal budget dRep setup"] + ? ["budget proposal auth setup","budget proposal dRep setup"] : [], - teardown: environments.ci && "cleanup dRep", + teardown: environments.ci && "cleanup artifacts", }, { name: "dRep", use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.dRep.spec.ts", dependencies: environments.ci - ? ["dRep setup", "dRep auth setup", "wallet bootstrap"] + ? ["dRep auth setup"] : [], - teardown: environments.ci && "cleanup dRep", + teardown: environments.ci && "cleanup artifacts", }, { name: "delegation", use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.delegation.spec.ts", dependencies: environments.ci - ? ["adaholder auth setup", "dRep setup", "wallet bootstrap"] + ? ["adaholder auth setup","dRep auth setup"] : [], teardown: environments.ci && "cleanup delegation", }, @@ -165,6 +162,7 @@ export default defineConfig({ "**/*.pd.spec.ts", "**/*.pb.spec.ts", ], + teardown: environments.ci && "cleanup artifacts", }, { name: "mobile", @@ -179,6 +177,7 @@ export default defineConfig({ "**/*.pb.spec.ts", "**/walletConnect.spec.ts", ], + teardown: environments.ci && "cleanup artifacts", }, { name: "cleanup delegation", @@ -192,5 +191,9 @@ export default defineConfig({ name: "cleanup faucet", testMatch: "faucet.teardown.ts", }, + { + name: "cleanup artifacts", + testMatch: "generated-artifacts.teardown.ts", + }, ], }); diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.dRep.spec.ts similarity index 95% rename from tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts rename to tests/govtool-frontend/playwright/tests/2-delegation/delegation.dRep.spec.ts index c712f7ec2..c7dc4bfea 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.dRep.spec.ts @@ -3,7 +3,10 @@ import { createTempDRepAuth } from "@datafactory/createAuth"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { + skipIfMainnet, + skipIfTemporyWalletIsNotAvailable, +} from "@helpers/cardano"; import { ShelleyWallet } from "@helpers/crypto"; import { createNewPageWithWallet } from "@helpers/page"; import DRepRegistrationPage from "@pages/dRepRegistrationPage"; @@ -14,6 +17,7 @@ import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("2. Delegation"); await skipIfMainnet(); + await skipIfTemporyWalletIsNotAvailable("registerDRepCopyWallets.json"); }); test("2N. Should show DRep information on details page", async ({ diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts index 0c5c1e2dd..573ffa93b 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts @@ -24,7 +24,10 @@ import { correctDRepDirectoryFormat, } from "@helpers/adaFormat"; import { setAllureEpic } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { + skipIfMainnet, + skipIfTemporyWalletIsNotAvailable, +} from "@helpers/cardano"; import { createNewPageWithWallet } from "@helpers/page"; import { waitForTxConfirmation } from "@helpers/transaction"; import DRepDirectoryPage from "@pages/dRepDirectoryPage"; @@ -36,6 +39,7 @@ import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("2. Delegation"); await skipIfMainnet(); + await skipIfTemporyWalletIsNotAvailable("registerDRepCopyWallets.json"); }); test.describe("Delegate to others", () => { diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts index f97449614..91fb769dd 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts @@ -5,7 +5,10 @@ import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; import { ShelleyWallet } from "@helpers/crypto"; -import { skipIfMainnet } from "@helpers/cardano"; +import { + skipIfMainnet, + skipIfTemporyWalletIsNotAvailable, +} from "@helpers/cardano"; import { createNewPageWithWallet } from "@helpers/page"; import { waitForTxConfirmation } from "@helpers/transaction"; import DRepRegistrationPage from "@pages/dRepRegistrationPage"; @@ -19,6 +22,7 @@ import { dRep01AuthFile } from "@constants/auth"; test.beforeEach(async () => { await setAllureEpic("3. DRep registration"); await skipIfMainnet(); + await skipIfTemporyWalletIsNotAvailable("registerDRepCopyWallets.json"); }); test.describe("Logged in DReps", () => { diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts index 35e20f006..554e63cd3 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts @@ -2,13 +2,12 @@ import { user01Wallet } from "@constants/staticWallets"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; -import { ShelleyWallet } from "@helpers/crypto"; import { invalid as mockInvalid, valid as mockValid } from "@mock/index"; import DRepRegistrationPage from "@pages/dRepRegistrationPage"; import { expect } from "@playwright/test"; -import environments from "@constants/environments"; import { user01AuthFile } from "@constants/auth"; import EditDRepPage from "@pages/editDRepPage"; +import { generateInvalidDRepInfo, generateValidDRepInfo } from "@helpers/dRep"; test.use({ storageState: user01AuthFile, @@ -62,27 +61,8 @@ test.describe("Validation of dRep Registration Form", () => { await expect(page.getByTestId("alert-success")).not.toBeVisible(); for (let i = 0; i < 100; i++) { - await dRepRegistrationPage.validateForm({ - name: mockValid.name(), - objectives: faker.lorem.paragraph(2), - motivations: faker.lorem.paragraph(2), - qualifications: faker.lorem.paragraph(2), - paymentAddress: (await ShelleyWallet.generate()).addressBech32( - environments.networkId - ), - linksReferenceLinks: [ - { - url: faker.internet.url(), - description: faker.internet.displayName(), - }, - ], - identityReferenceLinks: [ - { - url: faker.internet.url(), - description: faker.internet.displayName(), - }, - ], - }); + const validDRepInfo = await generateValidDRepInfo(); + await dRepRegistrationPage.validateForm(validDRepInfo); } for (let i = 0; i < 6; i++) { @@ -107,25 +87,8 @@ test.describe("Validation of dRep Registration Form", () => { await expect(page.getByTestId("alert-success")).not.toBeVisible(); for (let i = 0; i < 100; i++) { - await dRepRegistrationPage.inValidateForm({ - name: mockInvalid.name(), - objectives: faker.lorem.paragraph(40), - motivations: faker.lorem.paragraph(40), - qualifications: faker.lorem.paragraph(40), - paymentAddress: faker.string.alphanumeric(45), - linksReferenceLinks: [ - { - url: mockInvalid.url(), - description: faker.lorem.paragraph(20), - }, - ], - identityReferenceLinks: [ - { - url: mockInvalid.url(), - description: faker.lorem.paragraph(20), - }, - ], - }); + const invalidDRepInfo = generateInvalidDRepInfo(); + await dRepRegistrationPage.inValidateForm(invalidDRepInfo); } }); diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts index 59ee9f0eb..782df6ada 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts @@ -4,15 +4,20 @@ import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; import { ShelleyWallet } from "@helpers/crypto"; import { invalid as mockInvalid, valid as mockValid } from "@mock/index"; -import { skipIfMainnet } from "@helpers/cardano"; +import { + skipIfMainnet, + skipIfTemporyWalletIsNotAvailable, +} from "@helpers/cardano"; import EditDRepPage from "@pages/editDRepPage"; import { expect } from "@playwright/test"; import environments from "@constants/environments"; import { dRep02AuthFile } from "@constants/auth"; +import { generateInvalidDRepInfo, generateValidDRepInfo } from "@helpers/dRep"; test.beforeEach(async () => { await setAllureEpic("3. DRep registration"); await skipIfMainnet(); + await skipIfTemporyWalletIsNotAvailable("registerDRepCopyWallets.json"); }); test.use({ wallet: dRep02Wallet, storageState: dRep02AuthFile }); @@ -28,27 +33,8 @@ test.describe("Validation of edit dRep Form", () => { await expect(page.getByTestId("alert-success")).not.toBeVisible(); for (let i = 0; i < 100; i++) { - await editDRepPage.validateForm({ - name: mockValid.name(), - objectives: faker.lorem.paragraph(2), - motivations: faker.lorem.paragraph(2), - qualifications: faker.lorem.paragraph(2), - paymentAddress: (await ShelleyWallet.generate()).addressBech32( - environments.networkId - ), - linksReferenceLinks: [ - { - url: faker.internet.url(), - description: faker.internet.displayName(), - }, - ], - identityReferenceLinks: [ - { - url: faker.internet.url(), - description: faker.internet.displayName(), - }, - ], - }); + const validDRepInfo = await generateValidDRepInfo(); + await editDRepPage.validateForm(validDRepInfo); } for (let i = 0; i < 6; i++) { @@ -76,83 +62,55 @@ test.describe("Validation of edit dRep Form", () => { await expect(page.getByTestId("alert-success")).not.toBeVisible(); for (let i = 0; i < 100; i++) { - await editDRepPage.inValidateForm({ - name: mockInvalid.name(), - objectives: faker.lorem.paragraph(40), - motivations: faker.lorem.paragraph(40), - qualifications: faker.lorem.paragraph(40), - paymentAddress: faker.string.alphanumeric(45), - linksReferenceLinks: [ - { - url: mockInvalid.url(), - description: faker.lorem.paragraph(40), - }, - ], - identityReferenceLinks: [ - { - url: mockInvalid.url(), - description: faker.lorem.paragraph(40), - }, - ], - }); + const invalidDRepInfo = generateInvalidDRepInfo(); + await editDRepPage.inValidateForm(invalidDRepInfo); } }); - test("3N_1. Should accept valid metadata anchor on edit dRep", async ({ - page, - }) => { - const editDRepPage = new EditDRepPage(page); - await editDRepPage.goto(); - - const dRepName = "Test_DRep"; - await editDRepPage.nameInput.fill(dRepName); - - await editDRepPage.continueBtn.click(); - await page.getByRole("checkbox").click(); - await editDRepPage.registerBtn.click(); - - for (let i = 0; i < 100; i++) { - await editDRepPage.metadataUrlInput.fill(mockValid.url()); - await expect(page.getByTestId("invalid-url-error")).toBeHidden(); - } - }); - - test("3N_2. Should reject invalid dRep metadata anchor on edit dRep", async ({ - page, - }) => { - const editDRepPage = new EditDRepPage(page); - await editDRepPage.goto(); - - const dRepName = "Test_DRep"; - await editDRepPage.nameInput.fill(dRepName); - - await editDRepPage.continueBtn.click(); - await page.getByRole("checkbox").click(); - await editDRepPage.registerBtn.click(); - - for (let i = 0; i < 100; i++) { - const invalidUrl = mockInvalid.url(false); - await editDRepPage.metadataUrlInput.fill(invalidUrl); - if (invalidUrl.length <= 128) { - await expect(page.getByTestId("invalid-url-error")).toBeVisible(); - } else { - await expect( - page.getByTestId("url-must-be-less-than-128-bytes-error") - ).toBeVisible(); + test.describe("Metadata anchor Validation", () => { + let editDRepPage: EditDRepPage; + test.beforeEach(async ({ page }) => { + editDRepPage = new EditDRepPage(page); + await editDRepPage.goto(); + + const dRepName = faker.person.firstName(); + await editDRepPage.nameInput.fill(dRepName); + + await editDRepPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await editDRepPage.registerBtn.click(); + }); + test("3N_1. Should accept valid metadata anchor on edit dRep", async ({ + page, + }) => { + for (let i = 0; i < 100; i++) { + await editDRepPage.metadataUrlInput.fill(mockValid.url()); + await expect(page.getByTestId("invalid-url-error")).toBeHidden(); } - } - - const sentenceWithoutSpace = faker.lorem - .sentence(128) - .replace(/[\s.]/g, ""); - const metadataAnchorGreaterThan128Bytes = - faker.internet.url({ appendSlash: true }) + sentenceWithoutSpace; - - await editDRepPage.metadataUrlInput.fill(metadataAnchorGreaterThan128Bytes); - - await expect( - page.getByTestId("url-must-be-less-than-128-bytes-error") - ).toBeVisible(); + }); + + test("3N_2. Should reject invalid dRep metadata anchor on edit dRep", async ({ + page, + }) => { + for (let i = 0; i < 100; i++) { + const invalidUrl = mockInvalid.url(false); + const sentenceWithoutSpace = faker.lorem + .sentence({ min: 128, max: 500 }) + .replace(/[\s.]/g, ""); + const metadataAnchorGreaterThan128Bytes = + faker.internet.url({ appendSlash: true }) + sentenceWithoutSpace; + const checkedUrl = + Math.random() > 0.5 ? invalidUrl : metadataAnchorGreaterThan128Bytes; + await editDRepPage.metadataUrlInput.fill(checkedUrl); + if (checkedUrl.length <= 128) { + await expect(page.getByTestId("invalid-url-error")).toBeVisible(); + } else { + await expect( + page.getByTestId("url-must-be-less-than-128-bytes-error") + ).toBeVisible(); + } + } + }); }); }); diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts index b9ceb02a8..fd75c0b1d 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts @@ -8,6 +8,7 @@ import { isBootStrapingPhase, lovelaceToAda, skipIfMainnet, + skipIfTemporyWalletIsNotAvailable, } from "@helpers/cardano"; import { createNewPageWithWallet } from "@helpers/page"; import GovernanceActionsPage from "@pages/governanceActionsPage"; @@ -27,6 +28,7 @@ import { dRep01AuthFile } from "@constants/auth"; test.beforeEach(async () => { await setAllureEpic("4. Proposal visibility"); await skipIfMainnet(); + await skipIfTemporyWalletIsNotAvailable("registeredDRepCopyWallets.json"); }); test.describe("Logged in DRep", () => { diff --git a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts index 8a21e99f1..eb805f417 100644 --- a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts @@ -5,7 +5,11 @@ import { createTempDRepAuth } from "@datafactory/createAuth"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; -import { isBootStrapingPhase, skipIfMainnet } from "@helpers/cardano"; +import { + isBootStrapingPhase, + skipIfMainnet, + skipIfTemporyWalletIsNotAvailable, +} from "@helpers/cardano"; import { encodeCIP129Identifier } from "@helpers/encodeDecode"; import { createNewPageWithWallet } from "@helpers/page"; import { waitForTxConfirmation } from "@helpers/transaction"; @@ -13,13 +17,13 @@ import GovernanceActionDetailsPage from "@pages/governanceActionDetailsPage"; import GovernanceActionsPage from "@pages/governanceActionsPage"; import { Page, expect } from "@playwright/test"; import kuberService from "@services/kuberService"; -import { BootstrapGovernanceActionType, GovernanceActionType } from "@types"; -import { allure } from "allure-playwright"; +import { GovernanceActionType } from "@types"; import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("5. Proposal functionality"); await skipIfMainnet(); + await skipIfTemporyWalletIsNotAvailable("registeredDRepCopyWallets.json"); }); test.describe("Proposal checks", () => { @@ -180,7 +184,7 @@ test.describe("Perform voting", () => { await expect( govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("Yes") - ).toBeVisible(); + ).toBeVisible({ timeout: 60_000 }); govActionDetailsPage = await governanceActionsPage.viewFirstVotedProposal(); await govActionDetailsPage.reVote(); diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts index a9ab165f7..8e181bf1f 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts @@ -7,15 +7,20 @@ import { waitForTxConfirmation } from "@helpers/transaction"; import ProposalDiscussionPage from "@pages/proposalDiscussionPage"; import ProposalSubmissionPage from "@pages/proposalSubmissionPage"; import { expect } from "@playwright/test"; -import { skipIfMainnet } from "@helpers/cardano"; +import { + skipIfMainnet, + skipIfTemporyWalletIsNotAvailable, +} from "@helpers/cardano"; import { ProposalType } from "@types"; -import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; import walletManager from "lib/walletManager"; import { valid } from "@mock/index"; +import { rewardAddressBech32 } from "@helpers/shellyWallet"; +import { getWalletConfigForFaucet } from "@helpers/index"; test.beforeEach(async () => { await setAllureEpic("7. Proposal submission"); await skipIfMainnet(); + await skipIfTemporyWalletIsNotAvailable("proposalSubmissionWallets.json"); }); Object.values(ProposalType).forEach((proposalType, index) => { @@ -43,11 +48,13 @@ Object.values(ProposalType).forEach((proposalType, index) => { await proposalSubmissionPage.proposalCreateBtn.click(); await proposalDiscussionPage.continueBtn.click(); - await proposalSubmissionPage.createProposal( - proposalFaucetWallet, - proposalType + const rewardAddress = rewardAddressBech32( + environments.networkId, + getWalletConfigForFaucet().stake.pkh ); + await proposalSubmissionPage.createProposal(rewardAddress, proposalType); + await userPage.getByTestId("submit-as-GA-button").click(); await userPage.getByTestId("agree-checkbox").click(); diff --git a/tests/govtool-frontend/playwright/tests/9-outcomes/outcomes.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/9-outcomes/outcomes.loggedin.spec.ts new file mode 100644 index 000000000..79f61f98a --- /dev/null +++ b/tests/govtool-frontend/playwright/tests/9-outcomes/outcomes.loggedin.spec.ts @@ -0,0 +1,123 @@ +import { user01AuthFile } from "@constants/auth"; +import { InvalidMetadata } from "@constants/index"; +import { user01Wallet } from "@constants/staticWallets"; +import { test } from "@fixtures/walletExtension"; +import { setAllureEpic } from "@helpers/allure"; +import OutcomeDetailsPage from "@pages/outcomeDetailsPage"; +import OutComesPage from "@pages/outcomesPage"; +import { Page } from "@playwright/test"; + +const invalidOutcomeProposals = require("../../lib/_mock/outcome.json"); + +test.beforeEach(async () => { + await setAllureEpic("9. Outcomes"); +}); + +test.use({ + storageState: user01AuthFile, + wallet: user01Wallet, +}); + +test.describe("Outcomes page", () => { + let outcomePage: OutComesPage; + test.beforeEach(async ({ page }) => { + outcomePage = new OutComesPage(page); + }); + + test("9A_2. Should access Outcomes page in connected state", async () => { + await outcomePage.shouldAccessPage(); + }); + test.describe("outcome sorting and filtering", () => { + test("9C_1B. Should filter Governance Action Type on governance actions page", async () => { + test.slow(); + await outcomePage.goto(); + + await outcomePage.filterOutcomes(); + }); + + test("9C_2B. Should sort Governance Action Type on outcomes page", async () => { + test.slow(); + + await outcomePage.goto({ sort: "oldestFirst" }); + + await outcomePage.sortOutcomes(); + }); + + test("9C_3B. Should filter and sort Governance Action Type on outcomes page", async () => { + await outcomePage.filterAndSortOutcomes(); + }); + }); + + test("9E_2. Should verify all of the displayed governance actions have expired", async () => { + await outcomePage.goto(); + + await outcomePage.verifyAllOutcomesAreExpired(); + }); + + test("9F_2. Should load more Outcomes on show more", async () => { + await outcomePage.VerifyLoadMoreOutcomes(); + }); + + test.describe("Outcome details dependent test", () => { + let governanceActionId: string | undefined; + let governanceActionTitle: string | undefined; + let currentPage: Page; + test.beforeEach(async ({ page }) => { + const outcomePage = new OutComesPage(page); + const response = await outcomePage.fetchOutcomeIdAndTitleFromNetwork( + governanceActionId, + governanceActionTitle + ); + governanceActionId = response.governanceActionId; + governanceActionTitle = response.governanceActionTitle; + currentPage = page; + }); + + test("9B_2. Should search outcomes proposal by title and id", async () => { + // search by id + await outcomePage.searchOutcomesById(governanceActionId); + + await outcomePage.searchOutcomesByTitle(governanceActionTitle); + }); + + test("9D_2. Should copy governanceActionId in disconnect state", async ({ + context, + }) => { + await context.grantPermissions(["clipboard-read", "clipboard-write"]); + await outcomePage.shouldCopyGovernanceActionId(governanceActionId); + }); + }); +}); + +test.describe("Outcome details", () => { + test("9G_2. Should display correct vote counts on outcome details page", async ({ + browser, + page, + }) => { + const outcomeDetailPage = new OutcomeDetailsPage(page); + + await outcomeDetailPage.shouldDisplayCorrectVotingResults(browser, true); + }); + + test.describe("Invalid Outcome Metadata", () => { + InvalidMetadata.forEach(({ type, reason, url, hash }, index) => { + test(`9H_${index + 1}B: Should display "${type}" message in outcomes when ${reason}`, async ({ + page, + }) => { + const outcomeResponse = { + ...invalidOutcomeProposals[0], + url, + data_hash: hash, + }; + + const outcomeDetailPage = new OutcomeDetailsPage(page); + await outcomeDetailPage.verifyInvalidOutcomeMetadata({ + outcomeResponse, + type, + url, + hash, + }); + }); + }); + }); +}); diff --git a/tests/govtool-frontend/playwright/tests/9-outcomes/outcomes.spec.ts b/tests/govtool-frontend/playwright/tests/9-outcomes/outcomes.spec.ts index 0976ebb49..512ccca3a 100644 --- a/tests/govtool-frontend/playwright/tests/9-outcomes/outcomes.spec.ts +++ b/tests/govtool-frontend/playwright/tests/9-outcomes/outcomes.spec.ts @@ -1,20 +1,9 @@ import { InvalidMetadata } from "@constants/index"; import { test } from "@fixtures/walletExtension"; -import { formatWithThousandSeparator } from "@helpers/adaFormat"; import { setAllureEpic } from "@helpers/allure"; -import extractExpiryDateFromText from "@helpers/extractExpiryDateFromText"; -import { - areCCVoteTotalsDisplayed, - areDRepVoteTotalsDisplayed, - areSPOVoteTotalsDisplayed, -} from "@helpers/featureFlag"; -import { parseVotingPowerAndPercentage } from "@helpers/index"; -import { isMobile } from "@helpers/mobile"; -import { injectLogger } from "@helpers/page"; -import { functionWaitedAssert } from "@helpers/waitedLoop"; +import OutcomeDetailsPage from "@pages/outcomeDetailsPage"; import OutComesPage from "@pages/outcomesPage"; -import { expect, Page } from "@playwright/test"; -import { outcomeMetadata, outcomeProposal, outcomeType } from "@types"; +import { Page } from "@playwright/test"; const invalidOutcomeProposals = require("../../lib/_mock/outcome.json"); @@ -22,501 +11,107 @@ test.beforeEach(async () => { await setAllureEpic("9. Outcomes"); }); -const status = ["Expired", "Ratified", "Enacted", "Live"]; - -enum SortOption { - SoonToExpire = "Soon to expire", - NewestFirst = "Newest first", - OldestFirst = "Oldest first", - HighestAmountYesVote = "Highest amount of yes votes", -} -test("9A. Should access Outcomes page in disconnect state", async ({ - page, -}) => { - await page.goto("/"); - - if (isMobile(page)) { - await page.getByTestId("open-drawer-button").click(); - } - await page.getByTestId("governance-actions-outcomes-link").click(); - - await expect(page.getByText(/outcomes/i)).toHaveCount(2); -}); - -test.describe("Outcome details dependent test", () => { - let governanceActionId: string | undefined; - let governanceActionTitle: string | undefined; - let currentPage: Page; +test.describe("Outcomes page", () => { + let outcomePage: OutComesPage; test.beforeEach(async ({ page }) => { - // intercept outcomes data for id - await page.route( - "**/governance-actions?search=&filters=&sort=**", - async (route) => { - const response = await route.fetch(); - const data: outcomeProposal[] = await response.json(); - if (!governanceActionId) { - if (data.length > 0) { - const randomIndexForId = Math.floor(Math.random() * data.length); - governanceActionId = - data[randomIndexForId].tx_hash + - "#" + - data[randomIndexForId].index; - } - } - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify(data), - }); - } - ); - - // intercept metadata for title - await page.route("**/governance-actions/metadata?**", async (route) => { - try { - const response = await route.fetch(); - if (response.status() !== 200) { - await route.continue(); - return; - } - const data: outcomeMetadata = await response.json(); - if (!governanceActionTitle && data.data.title != null) { - governanceActionTitle = data.data.title; - } - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify(data), - }); - } catch (error) { - return; - } - }); - - const responsePromise = page.waitForResponse( - "**/governance-actions?search=&filters=&sort=**" - ); - const metadataResponsePromise = page.waitForResponse( - "**/governance-actions/metadata?**" - ); - - const outcomesPage = new OutComesPage(page); - await outcomesPage.goto(); - - await responsePromise; - await metadataResponsePromise; - currentPage = page; + outcomePage = new OutComesPage(page); }); - test("9B. Should search outcomes proposal by title and id", async ({}) => { - const outcomesPage = new OutComesPage(currentPage); - // search by id - await outcomesPage.searchInput.fill(governanceActionId); - await expect( - currentPage.getByRole("progressbar").getByRole("img") - ).toBeVisible(); - - await functionWaitedAssert( - async () => { - const idSearchOutcomeCards = await outcomesPage.getAllOutcomes(); - expect(idSearchOutcomeCards.length, { - message: - idSearchOutcomeCards.length == 0 && "No governance actions found", - }).toBeGreaterThan(0); - for (const outcomeCard of idSearchOutcomeCards) { - const id = await outcomeCard - .locator('[data-testid$="-CIP-105-id"]') - .textContent(); - expect(id.replace(/^.*ID/, "")).toContain(governanceActionId); - } - }, - { name: "search by id" } - ); - - // search by title - await outcomesPage.searchInput.fill(governanceActionTitle); - await expect( - currentPage.getByRole("progressbar").getByRole("img") - ).toBeVisible(); - - await functionWaitedAssert( - async () => { - const titleSearchOutcomeCards = await outcomesPage.getAllOutcomes(); - expect(titleSearchOutcomeCards.length, { - message: - titleSearchOutcomeCards.length == 0 && - "No governance actions found", - }).toBeGreaterThan(0); - for (const outcomeCard of titleSearchOutcomeCards) { - const title = await outcomeCard - .locator('[data-testid$="-card-title"]') - .textContent(); - expect(title.toLowerCase()).toContain( - governanceActionTitle.toLowerCase() - ); - } - }, - { name: "search by title" } - ); + test("9A_1. Should access Outcomes page in disconnect state", async () => { + await outcomePage.shouldAccessPage(); }); - test("9D. Should copy governanceActionId", async ({ page, context }) => { - await context.grantPermissions(["clipboard-read", "clipboard-write"]); - const outcomesPage = new OutComesPage(currentPage); - - await outcomesPage.searchInput.fill(governanceActionId); + test.describe("outcome sorting and filtering", () => { + test("9C_1A. Should filter Governance Action Type on governance actions page in disconnect state", async () => { + test.slow(); + await outcomePage.goto(); - await page - .getByTestId(`${governanceActionId}-CIP-105-id`) - .getByTestId("copy-button") - .click(); - await expect(page.getByText("Copied to clipboard")).toBeVisible({ - timeout: 60_000, + await outcomePage.filterOutcomes(); }); - const copiedTextDRepDirectory = await page.evaluate(() => - navigator.clipboard.readText() - ); - expect(copiedTextDRepDirectory).toEqual(governanceActionId); - }); -}); - -test("9C_1. Should filter Governance Action Type on governance actions page", async ({ - page, -}) => { - test.slow(); - - const outcomePage = new OutComesPage(page); - await outcomePage.goto(); - - await outcomePage.filterBtn.click(); - const filterOptionNames = Object.values(outcomeType); - - // proposal type filter - await outcomePage.applyAndValidateFilters( - filterOptionNames, - outcomePage._validateFiltersInOutcomeCard - ); - - // proposal status filter - await outcomePage.applyAndValidateFilters( - status, - outcomePage._validateStatusFiltersInOutcomeCard - ); -}); - -test("9C_2. Should sort Governance Action Type on outcomes page", async ({ - page, -}) => { - test.slow(); - - const outcomePage = new OutComesPage(page); - await outcomePage.goto({ sort: "oldestFirst" }); - - await outcomePage.sortBtn.click(); - - await outcomePage.sortAndValidate( - SortOption.NewestFirst, - (p1, p2) => p1.expiry_date >= p2.time - ); - - await outcomePage.sortAndValidate( - SortOption.OldestFirst, - (p1, p2) => p1.expiry_date <= p2.expiry_date - ); - - await outcomePage.sortAndValidate( - SortOption.HighestAmountYesVote, - (p1, p2) => parseInt(p1.yes_votes) >= parseInt(p2.yes_votes) - ); -}); - -test("9C_3. Should filter and sort Governance Action Type on outcomes page", async ({ - page, -}) => { - const outcomePage = new OutComesPage(page); - const filterOptionKeys = Object.keys(outcomeType); - const filterOptionNames = Object.values(outcomeType); - - const choice = Math.floor(Math.random() * filterOptionKeys.length); - await outcomePage.goto({ filter: filterOptionKeys[choice] }); - await outcomePage.sortBtn.click(); - - await outcomePage.sortAndValidate( - SortOption.OldestFirst, - (p1, p2) => p1.expiry_date <= p2.expiry_date - ); - - await outcomePage.validateFilters( - [filterOptionNames[choice]], - outcomePage._validateFiltersInOutcomeCard - ); -}); - -test("9E. Should verify all of the displayed governance actions have expired", async ({ - page, -}) => { - const outcomePage = new OutComesPage(page); - await outcomePage.goto(); - - const proposalCards = await outcomePage.getAllOutcomes(); - for (const proposalCard of proposalCards) { - const expiryDateEl = proposalCard.locator('[data-testid$="-Expired-date"]'); - const expiryDateTxt = await expiryDateEl.innerText(); - const expiryDate = extractExpiryDateFromText(expiryDateTxt); - const today = new Date(); - expect(today >= expiryDate).toBeTruthy(); - } -}); - -test("9F. Should load more Outcomes on show more", async ({ page }) => { - const responsePromise = page.waitForResponse((response) => - response - .url() - .includes(`governance-actions?search=&filters=&sort=newestFirst&page=2`) - ); - const outcomePage = new OutComesPage(page); - await outcomePage.goto(); - - let governanceActionIdsBefore: String[]; - let governanceActionIdsAfter: String[]; + test("9C_2A. Should sort Governance Action Type on outcomes page in disconnect state", async () => { + test.slow(); - await functionWaitedAssert( - async () => { - governanceActionIdsBefore = - await outcomePage.getAllListedCIP105GovernanceIds(); - await outcomePage.showMoreBtn.click(); - }, - { message: "Show more button not visible" } - ); + await outcomePage.goto({ sort: "oldestFirst" }); - const response = await responsePromise; - const governanceActionListAfter = await response.json(); - - await functionWaitedAssert( - async () => { - governanceActionIdsAfter = - await outcomePage.getAllListedCIP105GovernanceIds(); - expect(governanceActionIdsAfter.length).toBeGreaterThan( - governanceActionIdsBefore.length - ); - }, - { message: "Outcomes not loaded after clicking show more" } - ); + await outcomePage.sortOutcomes(); + }); - if (governanceActionListAfter.length >= governanceActionIdsBefore.length) { - await expect(outcomePage.showMoreBtn).toBeVisible(); - expect(true).toBeTruthy(); - } else { - await expect(outcomePage.showMoreBtn).not.toBeVisible(); - } -}); + test("9C_3A. Should filter and sort Governance Action Type on outcomes page in disconnect state", async () => { + await outcomePage.filterAndSortOutcomes(); + }); + }); -test("9G. Should display correct vote counts on outcome details page", async ({ - browser, -}) => { - await Promise.all( - Object.keys(outcomeType).map(async (filterKey) => { - const page = await browser.newPage(); - injectLogger(page); + test("9E_1. Should verify all of the displayed governance actions have expired in disconnect state", async () => { + await outcomePage.goto(); - const outcomeListResponsePromise = page.waitForResponse( - (response) => - response - .url() - .includes(`governance-actions?search=&filters=${filterKey}`), - { timeout: 60_000 } - ); + await outcomePage.verifyAllOutcomesAreExpired(); + }); - const metricsResponsePromise = page.waitForResponse( - (response) => response.url().includes(`/misc/network/metrics?epoch`), - { timeout: 60_000 } - ); + test("9F_1. Should load more Outcomes on show more in disconnect state", async () => { + await outcomePage.VerifyLoadMoreOutcomes(); + }); + test.describe("Outcome details dependent test", () => { + let governanceActionId: string | undefined; + let governanceActionTitle: string | undefined; + let currentPage: Page; + test.beforeEach(async ({ page }) => { const outcomePage = new OutComesPage(page); - await outcomePage.goto({ filter: filterKey }); - - const outcomeListResponse = await outcomeListResponsePromise; - const proposals = await outcomeListResponse.json(); - - expect( - proposals.length, - proposals.length == 0 && "No proposals found!" - ).toBeGreaterThan(0); - - const { - index: governanceActionIndex, - tx_hash: governanceTransactionHash, - } = proposals[0]; - - const outcomeResponsePromise = page.waitForResponse( - (response) => - response - .url() - .includes( - `governance-actions/${governanceTransactionHash}?index=${governanceActionIndex}` - ), - { timeout: 60_000 } + const response = await outcomePage.fetchOutcomeIdAndTitleFromNetwork( + governanceActionId, + governanceActionTitle ); + governanceActionId = response.governanceActionId; + governanceActionTitle = response.governanceActionTitle; - const govActionDetailsPage = await outcomePage.viewFirstOutcomes(); - - const outcomeResponse = await outcomeResponsePromise; - const proposalToCheck = (await outcomeResponse.json())[0]; - - const metricsResponse = await metricsResponsePromise; - - const { autoAbstain, noConfidence, sPosAutoAbstain, sPosNoConfidence } = - await govActionDetailsPage.getSposAndDRepAbstainNoConfidence( - metricsResponse - ); - - // check dRep votes - if (await areDRepVoteTotalsDisplayed(proposalToCheck)) { - await govActionDetailsPage.dRepExpandButton.click(); - - await expect( - govActionDetailsPage.dRepResultData.getByRole("row", { - name: "Yes", - }) - ).toHaveText( - `Yes${formatWithThousandSeparator(proposalToCheck.yes_votes, false)}`, - { - timeout: 60_000, - } - ); //BUG missing testIds - - await expect( - govActionDetailsPage.dRepResultData.getByRole("row", { - name: "Auto-Abstain", - }) - ).toHaveText(`Auto-Abstain${autoAbstain}`); //BUG missing testIds - await expect( - govActionDetailsPage.dRepResultData.getByRole("row", { - name: "No Confidence", - }) - ).toHaveText(`No Confidence${noConfidence}`); //BUG missing testIds - await expect( - govActionDetailsPage.dRepResultData.getByRole("row", { - name: "Explicit", - }) - ).toHaveText( - `Explicit${formatWithThousandSeparator(proposalToCheck.abstain_votes, false)}` - ); - - await expect( - govActionDetailsPage.dRepResultData - .getByRole("row", { - name: "No", - }) - .first() - ).toHaveText( - `No${formatWithThousandSeparator(proposalToCheck.no_votes, false)}` - ); //BUG missing testIds - } - - // check sPos votes - if (await areSPOVoteTotalsDisplayed(proposalToCheck)) { - await govActionDetailsPage.sPosExpandButton.click(); - const totalSposNoVotes = - parseInt(sPosNoConfidence.replace(/,/g, "")) + - proposalToCheck.pool_no_votes * 1000000; - - await expect( - govActionDetailsPage.sPosResultData.getByRole("row", { - name: "Yes", - }) - ).toHaveText( - `Yes${formatWithThousandSeparator(proposalToCheck.pool_yes_votes, false)}`, - { - timeout: 60_000, - } - ); //BUG missing testIds - - await expect( - govActionDetailsPage.sPosResultData.getByRole("row", { - name: "Auto-Abstain", - }) - ).toHaveText(`Auto-Abstain${sPosAutoAbstain}`); //BUG missing testIds - await expect( - govActionDetailsPage.sPosResultData.getByRole("row", { - name: "No Confidence", - }) - ).toHaveText(`No Confidence${sPosNoConfidence}`); //BUG missing testIds - await expect( - govActionDetailsPage.sPosResultData.getByRole("row", { - name: "Explicit", - }) - ).toHaveText( - `Explicit${formatWithThousandSeparator(proposalToCheck.pool_abstain_votes, false)}` - ); //BUG missing testIds - await expect( - govActionDetailsPage.sPosResultData - .getByRole("row", { - name: "No", - }) - .first() - ).toHaveText(`No${formatWithThousandSeparator(totalSposNoVotes)}`); //BUG missing testIds - } + currentPage = page; + }); - // check ccCommittee votes - if (areCCVoteTotalsDisplayed(proposalToCheck)) { - const ccYesVoteSubmittedText = - await govActionDetailsPage.ccCommitteeYesVotes.textContent(); - const ccNoVoteSubmittedText = - await govActionDetailsPage.ccCommitteeYesVotes.textContent(); - const { percentage: yesPercentage } = parseVotingPowerAndPercentage( - ccYesVoteSubmittedText - ); - const { percentage: noPercentage } = parseVotingPowerAndPercentage( - ccNoVoteSubmittedText - ); - await expect(govActionDetailsPage.ccCommitteeYesVotes).toHaveText( - `${proposalToCheck.cc_yes_votes} - ${yesPercentage}` - ); - await expect( - govActionDetailsPage.cCResultData.getByRole("row", { - name: "Abstain Votes", - }) - ).toHaveText(`Abstain Votes${proposalToCheck.pool_abstain_votes}`); //BUG missing testIds + test("9B_1. Should search outcomes proposal by title and id in disconnect state", async () => { + // search by id + await outcomePage.searchOutcomesById(governanceActionId); - await expect(govActionDetailsPage.ccCommitteeNoVotes).toHaveText( - `${proposalToCheck.cc_no_votes} - ${noPercentage}` - ); - } - }) - ); -}); + await outcomePage.searchOutcomesByTitle(governanceActionTitle); + }); -test.describe("Invalid Outcome Metadata", () => { - InvalidMetadata.forEach(({ type, reason, url, hash }, index) => { - test(`9H_${index + 1}: Should display "${type}" message in outcomes when ${reason}`, async ({ - page, + test("9D_1. Should copy governanceActionId in disconnect state", async ({ + context, }) => { - const outcomeResponse = { - ...invalidOutcomeProposals[0], - url, - data_hash: hash, - }; - - await page.route(/.*\/governance-actions\/[a-f0-9]{64}\?.*/, (route) => - route.fulfill({ body: JSON.stringify([outcomeResponse]) }) - ); + await context.grantPermissions(["clipboard-read", "clipboard-write"]); + await outcomePage.shouldCopyGovernanceActionId(governanceActionId); + }); + }); +}); - const outcomePage = new OutComesPage(page); - await outcomePage.goto(); - await outcomePage.viewFirstOutcomes(); - const outcomeTitle = await outcomePage.title.textContent(); +test.describe("Outcome details", () => { + test("9G_1. Should display correct vote counts on outcome details page in disconnect state", async ({ + browser, + page, + }) => { + const outcomeDetailPage = new OutcomeDetailsPage(page); + await outcomeDetailPage.shouldDisplayCorrectVotingResults(browser); + }); - await expect( - outcomePage.title, - outcomeTitle.toLowerCase() !== type.toLowerCase() && - `The URL "${url}" and hash "${hash}" do not match the expected properties for type "${type}".` - ).toHaveText(type, { - ignoreCase: true, - timeout: 60_000, + test.describe("Invalid Outcome Metadata", () => { + InvalidMetadata.forEach(({ type, reason, url, hash }, index) => { + test(`9H_${index + 1}A: Should display "${type}" message in outcomes when ${reason} in disconnect state`, async ({ + page, + }) => { + const outcomeResponse = { + ...invalidOutcomeProposals[0], + url, + data_hash: hash, + }; + + const outcomeDetailPage = new OutcomeDetailsPage(page); + await outcomeDetailPage.verifyInvalidOutcomeMetadata({ + outcomeResponse, + type, + url, + hash, + }); }); - await expect(outcomePage.metadataErrorLearnMoreBtn).toBeVisible(); }); }); }); diff --git a/tests/govtool-frontend/playwright/tests/dRep.setup.ts b/tests/govtool-frontend/playwright/tests/dRep.setup.ts index 25792139f..afb3c798c 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.setup.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.setup.ts @@ -1,7 +1,7 @@ import environments from "@constants/environments"; import { dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; import { uploadMetadataAndGetJsonHash } from "@helpers/metadata"; import { generateWallets } from "@helpers/shellyWallet"; import { pollTransaction } from "@helpers/transaction"; @@ -35,6 +35,9 @@ setup.beforeEach(async () => { }); setup("Register DRep of static wallets", async () => { + const totalRequiredBalanceForDRepSetup = + dRepWallets.length * (dRepDeposit / 1000000) + 2; + await skipIfBalanceIsInsufficient(totalRequiredBalanceForDRepSetup); setup.setTimeout(environments.txTimeOut); try { @@ -72,6 +75,10 @@ setup("Register DRep of static wallets", async () => { }); setup("Setup temporary DRep wallets", async () => { + const totalRequiredBalanceForDRepSetup = + (DREP_WALLETS_COUNT + REGISTER_DREP_WALLETS_COUNT) * + (dRepDeposit / 1000000 + 22); + await skipIfBalanceIsInsufficient(totalRequiredBalanceForDRepSetup); setup.setTimeout(3 * environments.txTimeOut); const dRepWallets: StaticWallet[] = await generateWallets(DREP_WALLETS_COUNT); diff --git a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts index 0e246b846..403da558c 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts @@ -4,7 +4,7 @@ import { dRepWallets, } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { expect } from "@playwright/test"; import { test as cleanup } from "@fixtures/walletExtension"; @@ -17,6 +17,7 @@ cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); await skipIfMainnet(); + await skipIfBalanceIsInsufficient(10); }); cleanup("DRep de-registration", async () => { diff --git a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts index f1d4b279b..02d264cce 100644 --- a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts @@ -1,7 +1,7 @@ import environments from "@constants/environments"; import { adaHolderWallets } from "@constants/staticWallets"; import { setAllureStory, setAllureEpic } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { test as cleanup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; @@ -11,6 +11,7 @@ cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); await skipIfMainnet(); + await skipIfBalanceIsInsufficient(10); }); cleanup(`Abstain delegation`, async () => { const stakePrivKeys = adaHolderWallets.map((wallet) => wallet.stake.private); diff --git a/tests/govtool-frontend/playwright/tests/faucet.setup.ts b/tests/govtool-frontend/playwright/tests/faucet.setup.ts deleted file mode 100644 index 129fc35b7..000000000 --- a/tests/govtool-frontend/playwright/tests/faucet.setup.ts +++ /dev/null @@ -1,31 +0,0 @@ -import environments from "@constants/environments"; -import { faucetWallet } from "@constants/staticWallets"; -import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; -import { pollTransaction } from "@helpers/transaction"; -import { test as setup } from "@fixtures/walletExtension"; -import { loadAmountFromFaucet } from "@services/faucetService"; -import kuberService from "@services/kuberService"; -import { functionWaitedAssert } from "@helpers/waitedLoop"; - -setup.describe.configure({ timeout: environments.txTimeOut }); - -setup.beforeEach(async () => { - await setAllureEpic("Setup"); - await setAllureStory("Faucet"); - await skipIfMainnet(); -}); - -setup("Faucet setup", async () => { - let balance: number; - functionWaitedAssert( - async () => { - balance = await kuberService.getBalance(faucetWallet.address); - }, - { message: "get balance" } - ); - - if (balance > 100_000) return; - const res = await loadAmountFromFaucet(faucetWallet.address); - await pollTransaction(res.txid); -}); diff --git a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts index 2a85236ed..40f61dd69 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts @@ -1,7 +1,7 @@ import environments from "@constants/environments"; import { allStaticWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { expect } from "@playwright/test"; import { test as cleanup } from "@fixtures/walletExtension"; @@ -14,6 +14,7 @@ cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); await skipIfMainnet(); + await skipIfBalanceIsInsufficient(10); }); cleanup("Refund faucet", async () => { diff --git a/tests/govtool-frontend/playwright/tests/generated-artifacts.teardown.ts b/tests/govtool-frontend/playwright/tests/generated-artifacts.teardown.ts new file mode 100644 index 000000000..5e9b4d1a3 --- /dev/null +++ b/tests/govtool-frontend/playwright/tests/generated-artifacts.teardown.ts @@ -0,0 +1,29 @@ +import environments from "@constants/environments"; +import { setAllureEpic, setAllureStory } from "@helpers/allure"; +import { test as cleanup } from "@fixtures/walletExtension"; +import { deleteFile, deleteFolder } from "@helpers/file"; + +cleanup.describe.configure({ timeout: environments.txTimeOut }); +cleanup.beforeEach(async () => { + await setAllureEpic("Setup"); + await setAllureStory("Cleanup"); +}); + +cleanup(`Clean up generated files and folders`, async () => { + const fileToRemove = [ + "registerDRepCopyWallets.json", + "registerDRepWallets.json", + "registeredDRepWallets.json", + "registeredDRepCopyWallets.json", + "protocolParameter.json", + ]; + + for (const fileName of fileToRemove) { + await deleteFile(fileName); + } + + const foldersToRemove = [".auth", ".download"]; + for (const folderName of foldersToRemove) { + await deleteFolder(folderName); + } +}); diff --git a/tests/govtool-frontend/playwright/tests/proposal-budget.dRep.setup.ts b/tests/govtool-frontend/playwright/tests/proposal-budget.dRep.setup.ts index 48137cc4c..0a91e509a 100644 --- a/tests/govtool-frontend/playwright/tests/proposal-budget.dRep.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal-budget.dRep.setup.ts @@ -4,7 +4,7 @@ import { dRepWallets, } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; import { uploadMetadataAndGetJsonHash } from "@helpers/metadata"; import { pollTransaction } from "@helpers/transaction"; import { expect } from "@playwright/test"; @@ -16,6 +16,7 @@ setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Register DRep"); await skipIfMainnet(); + await skipIfBalanceIsInsufficient(502 * budgetProposalDRepWallets.length); }); setup("Register DRep of proposal budget static wallets", async () => { diff --git a/tests/govtool-frontend/playwright/tests/proposal.setup.ts b/tests/govtool-frontend/playwright/tests/proposal.setup.ts index 9f905b426..d9511b483 100644 --- a/tests/govtool-frontend/playwright/tests/proposal.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal.setup.ts @@ -1,13 +1,13 @@ import environments from "@constants/environments"; -import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; import { generateWallets } from "@helpers/shellyWallet"; import { pollTransaction } from "@helpers/transaction"; import { test as setup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; import walletManager from "lib/walletManager"; import { functionWaitedAssert } from "@helpers/waitedLoop"; +import { getWalletConfigForFaucet } from "@helpers/index"; const PROPOSAL_WALLETS_COUNT = 4; @@ -27,6 +27,10 @@ setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Proposal"); await skipIfMainnet(); + const totalRequiredBalanceForWallets = + (govActionDeposit / 1000000) * PROPOSAL_WALLETS_COUNT + + 22 * PROPOSAL_WALLETS_COUNT; + await skipIfBalanceIsInsufficient(totalRequiredBalanceForWallets); }); setup("Setup temporary proposal wallets", async () => { @@ -37,8 +41,8 @@ setup("Setup temporary proposal wallets", async () => { // initialize wallets const initializeRes = await kuberService.initializeWallets( [...proposalWallets], - proposalFaucetWallet.address, - proposalFaucetWallet.payment.private + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private ); await pollTransaction(initializeRes.txId, initializeRes.lockInfo); @@ -47,8 +51,8 @@ setup("Setup temporary proposal wallets", async () => { }); const transferRes = await kuberService.multipleTransferADA( amountOutputs, - proposalFaucetWallet.address, - proposalFaucetWallet.payment.private + getWalletConfigForFaucet().address, + getWalletConfigForFaucet().payment.private ); // save to file await walletManager.writeWallets(proposalWallets, "proposalSubmission"); diff --git a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts index 33321c781..8557765d6 100644 --- a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts +++ b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts @@ -1,24 +1,25 @@ import { adaHolderWallets, dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfMainnet } from "@helpers/cardano"; +import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { expect } from "@playwright/test"; import { test as setup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; import environments from "lib/constants/environments"; -setup.describe.configure({ mode: "serial", timeout: environments.txTimeOut }); +const totalWalletsToInitialize = [...adaHolderWallets, ...dRepWallets]; setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Wallet bootstrap"); await skipIfMainnet(); + await skipIfBalanceIsInsufficient(22 * totalWalletsToInitialize.length); }); setup("Initialize static wallets", async () => { + setup.setTimeout(environments.txTimeOut); try { - const wallets = [...adaHolderWallets, ...dRepWallets]; - const res = await kuberService.initializeWallets(wallets); + const res = await kuberService.initializeWallets(totalWalletsToInitialize); await pollTransaction(res.txId); } catch (err) { if (err.status === 400 && err.message.includes("StakeKeyRegisteredDELEG")) { diff --git a/tests/load-testing/src/test/java/org/cardano/govtool/feeders/DrepListFetcher.java b/tests/load-testing/src/test/java/org/cardano/govtool/feeders/DrepListFetcher.java index ae85fe931..3d790f138 100644 --- a/tests/load-testing/src/test/java/org/cardano/govtool/feeders/DrepListFetcher.java +++ b/tests/load-testing/src/test/java/org/cardano/govtool/feeders/DrepListFetcher.java @@ -22,7 +22,7 @@ public static List fetchDrepIds(String baseUrl) { // Fetch about 5 pages for (int page = 0; page < 5; page++) { - String requestUrl = baseUrl + "/drep/list" + "?page=" + page + "&size=" + PAGE_SIZE; + String requestUrl = baseUrl + "drep/list" + "?page=" + page + "&size=" + PAGE_SIZE; HttpRequest request = HttpRequest.newBuilder() .uri(new URI(requestUrl)) .GET() diff --git a/tests/load-testing/src/test/java/org/cardano/govtool/simulations/VvaSimulation.java b/tests/load-testing/src/test/java/org/cardano/govtool/simulations/VvaSimulation.java index 37c3a4586..5c6591b1b 100644 --- a/tests/load-testing/src/test/java/org/cardano/govtool/simulations/VvaSimulation.java +++ b/tests/load-testing/src/test/java/org/cardano/govtool/simulations/VvaSimulation.java @@ -53,7 +53,7 @@ private PopulationBuilder makeScenario(String name, ChainBuilder chain, double u // Load Simulation { knownDreps= DrepListFetcher.fetchDrepIds(API_URL); - var DREP_USER_RATI0=0.3 + var DREP_USER_RATI0=0.3; setUp( makeScenario("User Connects and Leave", exec(), 0.1) , makeScenario("User Registers as Drep",