├── .gitignore ├── midl-dev-logo.png ├── polkadot-sidecar ├── requirements.txt ├── wsgi.py ├── Dockerfile └── polkadot_sidecar.py ├── polkadot-payout-cron ├── src │ ├── index.d.ts │ └── index.ts ├── package.json ├── Dockerfile ├── tsconfig.json ├── yarn.lock └── package-lock.json ├── polkadot-archive-downloader ├── Dockerfile └── entrypoint.sh ├── polkadot-session-key-check ├── package.json ├── Dockerfile ├── index.ts └── tsconfig.json ├── charts ├── polkadot-payout │ ├── README.md │ ├── templates │ │ ├── secrets.yaml │ │ └── cronjob.yaml │ ├── .helmignore │ ├── values.yaml │ └── Chart.yaml ├── polkadot-votebot │ ├── templates │ │ ├── secrets.yaml │ │ └── cronjob.yaml │ ├── README.md │ ├── Chart.yaml │ └── values.yaml └── polkadot │ ├── templates │ ├── services.yaml │ ├── servicemonitor.yaml │ ├── secrets.yaml │ ├── configmap.yaml │ ├── networkpolicy.yaml │ ├── session-key-check-cron.yaml │ └── statefulset.yaml │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── scripts │ └── polkadot-node.sh │ └── values.yaml ├── polkadot-votebot-gov2-cron ├── Dockerfile ├── package.json ├── tsconfig.json └── index.ts ├── polkadot-node-key-configurator ├── Dockerfile └── entrypoint.sh ├── README.md ├── .github └── workflows │ └── ci.yml └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | terraform/terraform.tfvars 2 | .env* 3 | -------------------------------------------------------------------------------- /midl-dev-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midl-dev/polkadot-k8s/HEAD/midl-dev-logo.png -------------------------------------------------------------------------------- /polkadot-sidecar/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | requests 3 | gunicorn 4 | python-dateutil 5 | -------------------------------------------------------------------------------- /polkadot-payout-cron/src/index.d.ts: -------------------------------------------------------------------------------- 1 | import '@polkadot/api-augment/kusama'; 2 | import '@polkadot/types'; 3 | -------------------------------------------------------------------------------- /polkadot-sidecar/wsgi.py: -------------------------------------------------------------------------------- 1 | from polkadot_sidecar import application 2 | 3 | if __name__ == "__main__": 4 | application.run() 5 | -------------------------------------------------------------------------------- /polkadot-archive-downloader/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk add --no-cache lz4 bash 3 | COPY entrypoint.sh / 4 | ENTRYPOINT ["/entrypoint.sh"] 5 | CMD [] 6 | -------------------------------------------------------------------------------- /polkadot-sidecar/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine 2 | WORKDIR /build 3 | COPY . /build 4 | ENV PYTHONUNBUFFERED=1 5 | RUN pip install -r requirements.txt 6 | ENTRYPOINT ["gunicorn", "-b", ":31764", "wsgi" ] 7 | -------------------------------------------------------------------------------- /polkadot-session-key-check/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "npx tsc -d" 4 | }, 5 | "dependencies": { 6 | "@polkadot/api": "^8.12.2", 7 | "@slack/web-api": "^6.6.0", 8 | "typescript": "^4.7.4" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /charts/polkadot-payout/README.md: -------------------------------------------------------------------------------- 1 | # Polkadot payout cron 2 | 3 | A chart that deploys a payout cronjob. It does not include a polkadot node, you need to provide a node URI. Node can be deployed using the "polkadot" chart. 4 | 5 | ## Parameters 6 | 7 | Please see `values.yaml` 8 | -------------------------------------------------------------------------------- /polkadot-payout-cron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@polkadot/api": "^11.2.1", 4 | "@polkadot/types": "^11.2.1", 5 | "@slack/web-api": "^7.0.4", 6 | "typescript": "^5.4.5" 7 | }, 8 | "scripts": { 9 | "build": "npx tsc -d" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /polkadot-session-key-check/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-alpine 2 | 3 | WORKDIR /app 4 | 5 | COPY . /app 6 | 7 | RUN ls 8 | RUN npm install 9 | RUN npm run build 10 | RUN npm cache clean --force --loglevel=error 11 | 12 | CMD [ "node", "--unhandled-rejections=strict", "index.js" ] 13 | -------------------------------------------------------------------------------- /polkadot-votebot-gov2-cron/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20-alpine 2 | 3 | WORKDIR /app 4 | 5 | COPY . /app 6 | 7 | RUN ls 8 | RUN npm install 9 | RUN npm run build 10 | RUN npm cache clean --force --loglevel=error 11 | 12 | CMD [ "node", "--unhandled-rejections=strict", "index.js" ] 13 | -------------------------------------------------------------------------------- /charts/polkadot-payout/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | payout-account-mnemonic: {{ b64enc .Values.payout_account_mnemonic }} 4 | slack-alert-token: {{ b64enc .Values.slack_alert_token }} 5 | kind: Secret 6 | metadata: 7 | name: polkadot-payout-secrets 8 | namespace: {{ .Release.Namespace }} 9 | -------------------------------------------------------------------------------- /charts/polkadot-votebot/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | proxy-account-mnemonic: {{ b64enc .Values.proxy_account_mnemonic }} 4 | slack-alert-token: {{ b64enc .Values.slack_alert_token }} 5 | kind: Secret 6 | metadata: 7 | name: polkadot-proxy-secrets 8 | namespace: {{ .Release.Namespace }} 9 | -------------------------------------------------------------------------------- /charts/polkadot/templates/services.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: private-node 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: polkadot-node 9 | spec: 10 | ports: 11 | - port: 9944 12 | name: rpc 13 | - port: 9615 14 | name: metrics 15 | selector: 16 | app: polkadot-node 17 | clusterIP: None 18 | -------------------------------------------------------------------------------- /polkadot-node-key-configurator/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM parity/subkey:2.0.2 2 | USER root 3 | # install tools and dependencies 4 | RUN apt-get update --allow-insecure-repositories && \ 5 | DEBIAN_FRONTEND=noninteractive apt-get install -y \ 6 | xxd && \ 7 | apt-get autoremove -y && \ 8 | apt-get clean && \ 9 | find /var/lib/apt/lists/ -type f -not -name lock -delete; 10 | COPY entrypoint.sh / 11 | ENTRYPOINT ["/entrypoint.sh"] 12 | CMD [] 13 | -------------------------------------------------------------------------------- /polkadot-votebot-gov2-cron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "npx tsc -d" 4 | }, 5 | "dependencies": { 6 | "@polkadot/api": "^11.2.1", 7 | "@polkadot/types-augment": "^11.2.1", 8 | "@slack/web-api": "^6.10.0", 9 | "axios": "^1.6.2", 10 | "follow-redirects": "^1.15.3", 11 | "js-yaml": "^4.1.0", 12 | "node-fetch": "^3.3.2", 13 | "request": "^2.88.2", 14 | "ts-node": "^10.9.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /charts/polkadot-votebot/README.md: -------------------------------------------------------------------------------- 1 | # Polkadot vote bot cron 2 | 3 | A chart that deploys a polkadot governance referendum voting cronjob. It does not include a polkadot node, you need to provide a node URI. Node can be deployed using the "polkadot" chart. 4 | 5 | Votes are sourced from a github repository in yaml format. Use your own or the example https://github.com/midl-dev/dotsama-votes 6 | 7 | ## Parameters 8 | 9 | Please see `values.yaml` 10 | -------------------------------------------------------------------------------- /polkadot-payout-cron/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20-alpine 2 | 3 | RUN mkdir /home/node/app/ && chown -R node:node /home/node/app 4 | 5 | WORKDIR /home/node/app 6 | 7 | COPY --chown=node:node package*.json yarn.lock tsconfig.json ./ 8 | 9 | COPY --chown=node:node src/ ./src 10 | 11 | USER node 12 | 13 | RUN npm install && npm run build && npm cache clean --force --loglevel=error 14 | 15 | CMD [ "node", "--unhandled-rejections=strict", "build/index.js" ] 16 | -------------------------------------------------------------------------------- /charts/polkadot/templates/servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.deploy_service_monitor }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | labels: 6 | app: polkadot-metrics 7 | name: polkadot-service-monitor 8 | namespace: {{ .Release.Namespace }} 9 | spec: 10 | endpoints: 11 | - interval: 15s 12 | port: metrics 13 | path: /metrics 14 | selector: 15 | matchLabels: 16 | app: polkadot-node 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /charts/polkadot/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/polkadot-payout/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/polkadot/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.session_key_check.enabled }} 2 | --- 3 | apiVersion: v1 4 | data: 5 | slack-alert-token: {{ b64enc .Values.session_key_check.slack_alert_token }} 6 | kind: Secret 7 | metadata: 8 | name: polkadot-val-secrets 9 | namespace: {{ .Release.Namespace }} 10 | {{- end }} 11 | --- 12 | apiVersion: v1 13 | data: 14 | {{- range $k, $v := .Values.local_nodes }} 15 | {{ $k }}: {{ $v | b64enc }} 16 | {{- end }} 17 | kind: Secret 18 | metadata: 19 | name: polkadot-node-keys 20 | namespace: {{ .Release.Namespace }} 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Polkadot-k8s 2 | 3 | This project is a collection of helm charts to help you deploy [Polkadot](https://polkadot.network) or [Kusama](https://kusama.network) validation infrastructure. 4 | 5 | Features: 6 | 7 | * compatible with Kusama and Polkadot 8 | * includes a [payout cronjob](charts/polkadot-payout) for automated payouts 9 | * includes a [vote bot](charts/polkadot-votebot) for easy governance voting 10 | 11 | Brought to you by MIDL.dev 12 | -------------------------- 13 | 14 | MIDL.dev 15 | 16 | We help you deploy and manage a complete Polkadot or Kusama validator infrastructure for you. [Hire us](https://midl.dev). 17 | -------------------------------------------------------------------------------- /charts/polkadot/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | data: 4 | ARCHIVE_URL: "{{ .Values.polkadot_archive_url }}" 5 | TELEMETRY_URL: "{{ .Values.polkadot_telemetry_url }}" 6 | {{- if .Values.no_telemetry }} 7 | NO_TELEMETRY: "true" 8 | {{- end }} 9 | VALIDATOR_NAME: "{{ .Values.polkadot_validator_name }}" 10 | OUT_PEERS: "{{ .Values.number_of_out_peers }}" 11 | IN_PEERS: "{{ .Values.number_of_in_peers }}" 12 | CHAIN: "{{ .Values.chain}}" 13 | NAMESPACE: "{{ .Release.Namespace }}" 14 | PUBLIC_MULTIADDR: "/ip4/{{ .Values.p2p_ip }}/tcp/{{ .Values.p2p_port }}" 15 | NO_HARDWARE_BENCHMARKS: "{{ .Values.no_hardware_benchmarks }}" 16 | kind: ConfigMap 17 | metadata: 18 | name: polkadot-configmap 19 | namespace: {{ .Release.Namespace }} 20 | -------------------------------------------------------------------------------- /charts/polkadot-payout/values.yaml: -------------------------------------------------------------------------------- 1 | polkadot_k8s_images: 2 | polkadot_payout_cron: ghcr.io/midl-dev/polkadot-payout-cron:master 3 | # to deploy in a specific node pool, put label here 4 | node_selector: {} 5 | stash_account_address: "your stash" 6 | stash_account_alias: "an alias so you recognize your account when getting an alert (if you have several" 7 | payout_account_alias: "an alias for the payout account (displayed in the logs for convenience)" 8 | slack_alert_channel: "the slack channel where you want to receive the alert" 9 | node_endpoint: "the uri of the polkadot node used to send the payout operation" 10 | num_past_eras: "how many eras past should the script check for missing payouts?" 11 | chain: "kusama" 12 | 13 | # schedule in cron format. example below: every 3 hours, 2 minutes past the hour 14 | cron_schedule: "2 */3 * * *" 15 | 16 | # sensitive 17 | payout_account_mnemonic: "12 word secret seed for an account that's paying for the fees associated with the payout operation. put very little money on it" 18 | slack_alert_token: "the token to connect to slack and send alerts" 19 | -------------------------------------------------------------------------------- /polkadot-node-key-configurator/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | rm -vf /polkadot/k8s_local_node_key 7 | rm -rvf /polkadot/k8s_node_ids/ 8 | mkdir -p /polkadot/k8s_node_ids 9 | 10 | # write private key for this node only and protect it 11 | if [ -f /polkadot-node-keys/${NAMESPACE} ]; then 12 | cat /polkadot-node-keys/${NAMESPACE} | xxd -r -p > /polkadot/k8s_local_node_key 13 | # move owner to polkadot 14 | chown 1000 /polkadot/k8s_local_node_key 15 | chmod 400 /polkadot/k8s_local_node_key 16 | fi 17 | 18 | 19 | for node in $(ls /polkadot-node-keys) 20 | do 21 | # do not peer with myself 22 | if [ "${node}" != "${NAMESPACE}" ] 23 | then 24 | if [ ! -f /polkadot/k8s_local_peer_cmd ]; then 25 | # write public keys for all peers in an env file, to be sourced by polkadot startup script 26 | echo "--reserved-nodes " > /polkadot/k8s_local_peer_cmd 27 | fi 28 | echo "/dns4/${CHAIN}-node-0.${CHAIN}-node.${node}/tcp/30333/p2p/$(subkey inspect-node-key --file /polkadot-node-keys/$node) " >> /polkadot/k8s_local_peer_cmd 29 | fi 30 | done 31 | -------------------------------------------------------------------------------- /charts/polkadot/templates/networkpolicy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.k8s.io/v1 3 | kind: NetworkPolicy 4 | metadata: 5 | name: polkadot-private-node-policy 6 | namespace: default 7 | namespace: {{ .Release.Namespace }} 8 | spec: 9 | podSelector: 10 | matchLabels: 11 | app: private-node 12 | policyTypes: 13 | - Ingress 14 | - Egress 15 | egress: 16 | - ports: 17 | - port: 53 18 | protocol: TCP 19 | - port: 53 20 | protocol: UDP 21 | - port: 443 22 | protocol: TCP 23 | - port: 30333 24 | protocol: TCP 25 | - port: 30334 26 | protocol: TCP 27 | - port: 30100 28 | protocol: TCP 29 | ingress: 30 | - ports: 31 | - port: {{ .Values.p2p_port }} 32 | protocol: TCP 33 | - ports: 34 | - port: 9615 35 | protocol: TCP 36 | from: 37 | - namespaceSelector: 38 | matchLabels: {} 39 | podSelector: 40 | matchLabels: 41 | app: prometheus 42 | - ports: 43 | - port: 9944 44 | protocol: TCP 45 | from: 46 | - podSelector: 47 | matchLabels: 48 | app: polkadot-payout-cron 49 | -------------------------------------------------------------------------------- /polkadot-archive-downloader/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [ "${CHAIN}" == "polkadot" ]; then 7 | chain_dir=polkadot 8 | else 9 | chain_dir=ksmcc3 10 | fi 11 | 12 | if [ -d /polkadot/.local/share/polkadot/chains/${chain_dir}/*db/ ]; then 13 | echo "Blockchain database already exists, no need to import, exiting" 14 | exit 0 15 | elif [ -z "$ARCHIVE_URL" ]; then 16 | echo "No archive download url specified, exiting" 17 | exit 0 18 | else 19 | echo "Did not find pre-existing data, importing blockchain" 20 | rm -rf /polkadot/.local/share/polkadot/chains/${chain_dir}-tmp/ || true 21 | mkdir -p /polkadot/.local/share/polkadot/chains/${chain_dir}-tmp/ 22 | echo "Will download $ARCHIVE_URL" 23 | wget -O - $ARCHIVE_URL | lz4 -c -d - | tar -x -C /polkadot/.local/share/polkadot/chains/${chain_dir}-tmp 24 | echo "Download successful, moving to final location" 25 | mv -v /polkadot/.local/share/polkadot/chains/${chain_dir}-tmp/ /polkadot/.local/share/polkadot/chains/${chain_dir}/ 26 | chmod -R 777 /polkadot/.local/ 27 | chown -R 1000:1000 /polkadot/.local/ 28 | fi 29 | -------------------------------------------------------------------------------- /charts/polkadot/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: polkadot 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.16.0 24 | -------------------------------------------------------------------------------- /charts/polkadot/README.md: -------------------------------------------------------------------------------- 1 | # Polkadot helm chart 2 | 3 | This deploys a polkadot node. 4 | 5 | It can: 6 | 7 | * sync from a filesystem archive 8 | * configure its own host key passed as parameter 9 | * connect to other nodes in different namespaces in a full mesh 10 | * deploy a network load balancer for p2p ingress in a cloud setup 11 | 12 | ## How to deploy 13 | 14 | See values.yaml comments for detailed explanation of all possible values. 15 | 16 | ## Example 17 | 18 | Deploy val1 chart in namespace `val1`: 19 | 20 | ``` 21 | polkadot_validator_name: "val1" 22 | polkadot_archive_url: null 23 | p2p_ip: 10.0.0.1 24 | p2p_port: 30333 25 | local_nodes: 26 | nico: 9cd2bad53ae93f45ae19d62f7961679972b9099935ce29d00c2e23efbf2c40bf 27 | nico2: 9cd2bad53ae93f45ae19d62f7961679972b9099935ce29d00c2e23efbf2c40be 28 | ``` 29 | 30 | Deploy val2 chart in namespace `val2`: 31 | 32 | ``` 33 | polkadot_validator_name: "val2" 34 | polkadot_archive_url: null 35 | p2p_ip: 10.0.0.1 36 | p2p_port: 30334 37 | local_nodes: 38 | nico: 9cd2bad53ae93f45ae19d62f7961679972b9099935ce29d00c2e23efbf2c40bf 39 | nico2: 9cd2bad53ae93f45ae19d62f7961679972b9099935ce29d00c2e23efbf2c40be 40 | ``` 41 | 42 | These 2 validators will extablish p2p peering with each other. 43 | -------------------------------------------------------------------------------- /charts/polkadot-payout/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: polkadot-payout 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /charts/polkadot-votebot/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: polkadot-votebot 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /charts/polkadot-votebot/values.yaml: -------------------------------------------------------------------------------- 1 | polkadot_k8s_images: 2 | polkadot_votebot_cron: ghcr.io/midl-dev/polkadot-votebot-cron:master 3 | polkadot_votebot_gov2_cron: ghcr.io/midl-dev/polkadot-votebot-gov2-cron:master 4 | # to deploy in a specific node pool, put label here 5 | node_selector: {} 6 | stash_account_address: "your validator stash account on-chain address" 7 | stash_account_alias: "an alias so you recognize your account when getting an alert (if you have several" 8 | proxy_account_alias: "an alias for the proxy account (displayed in the logs for convenience)" 9 | slack_alert_channel: "the slack channel where you want to receive the alert" 10 | node_endpoint: "the uri of the polkadot node used to send the vote operation" 11 | 12 | # the repository where you keep your vote suggestions metadata 13 | vote_repo: "midl-dev/dotsama-votes" 14 | 15 | # chain: kusama or polkadot 16 | chain: "kusama" 17 | 18 | # schedule in cron format. example below: every 3 hours, 2 minutes past the hour 19 | cron_schedule: "2 */3 * * *" 20 | 21 | # sensitive 22 | proxy_account_mnemonic: "12 word secret seed for your proxy account. it must be registered on-chain as goverenane proxy for your stash. put very little money on it" 23 | slack_alert_token: "the token to connect to slack and send alerts" 24 | 25 | skip_gov1: false 26 | 27 | -------------------------------------------------------------------------------- /charts/polkadot/templates/session-key-check-cron.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.session_key_check.enabled }} 2 | apiVersion: batch/v1 3 | kind: CronJob 4 | metadata: 5 | name: polkadot-session-key-check 6 | namespace: {{ .Release.Namespace }} 7 | spec: 8 | schedule: {{ .Values.session_key_check.cron_schedule }} 9 | concurrencyPolicy: Forbid 10 | jobTemplate: 11 | spec: 12 | template: 13 | metadata: 14 | labels: 15 | app: polkadot-session-key-check 16 | spec: 17 | nodeSelector: 18 | {{ toYaml .Values.node_selector | indent 12 }} 19 | containers: 20 | - name: polkadot-session-key-check 21 | image: {{ .Values.polkadot_k8s_images.polkadot_session_key_check }} 22 | env: 23 | - name: "SLACK_ALERT_TOKEN" 24 | valueFrom: 25 | secretKeyRef: 26 | name: polkadot-val-secrets 27 | key: slack-alert-token 28 | - name: "STASH_ACCOUNT_ADDRESS" 29 | value: "{{ .Values.session_key_check.stash_account_address }}" 30 | - name: "STASH_ACCOUNT_ALIAS" 31 | value: "{{ .Values.session_key_check.stash_account_alias }}" 32 | - name: "SLACK_ALERT_CHANNEL" 33 | value: "{{ .Values.session_key_check.slack_alert_channel }}" 34 | - name: "NODE_ENDPOINT" 35 | value: "private-node" 36 | - name: "CHAIN" 37 | value: "{{ .Values.chain }}" 38 | resources: 39 | limits: 40 | cpu: 0 41 | imagePullPolicy: IfNotPresent 42 | restartPolicy: OnFailure 43 | {{- end }} 44 | -------------------------------------------------------------------------------- /charts/polkadot/scripts/polkadot-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [ -e /polkadot/k8s_local_node_key ]; then 7 | node_key_param="--node-key-file /polkadot/k8s_local_node_key" 8 | fi 9 | 10 | if [ -e /polkadot/k8s_local_peer_cmd ]; then 11 | local_peer_param="$(cat /polkadot/k8s_local_peer_cmd)" 12 | fi 13 | 14 | if [ ! -z "$VALIDATOR_NAME" ]; then 15 | name_param="--name \"$VALIDATOR_NAME\"" 16 | fi 17 | 18 | if [ ! -z "$CHAIN" ]; then 19 | chain_param="--chain \"$CHAIN\"" 20 | fi 21 | 22 | if [ ! -z "$IN_PEERS" ]; then 23 | in_peers_param="--in-peers=${IN_PEERS}" 24 | fi 25 | 26 | if [ ! -z "$OUT_PEERS" ]; then 27 | out_peers_param="--out-peers=${OUT_PEERS}" 28 | fi 29 | 30 | if [ ! -z "$NO_TELEMETRY" ]; then 31 | no_telemetry_param="--no-telemetry" 32 | fi 33 | 34 | if [ ! -z "$TELEMETRY_URL" ]; then 35 | telemetry_url_param="--telemetry-url \"$TELEMETRY_URL 1\"" 36 | fi 37 | 38 | if [ ! -z "$PUBLIC_MULTIADDR" ]; then 39 | public_address_param="--public-addr=${PUBLIC_MULTIADDR}" 40 | fi 41 | 42 | if [ ! -z "$NO_HARDWARE_BENCHMARKS" ] && [ "$NO_HARDWARE_BENCHMARKS" == "true" ]; then 43 | hw_bench_param="--no-hardware-benchmarks" 44 | fi 45 | 46 | if [ "$CHAIN" == "kusama" ]; then 47 | litep2p_param="--network-backend litep2p" 48 | fi 49 | 50 | # sleep 1000 51 | eval /usr/bin/polkadot --validator --wasm-execution Compiled \ 52 | --base-path=/polkadot/.local/share/polkadot/ \ 53 | --state-pruning=256 \ 54 | --blocks-pruning=256 \ 55 | --prometheus-external \ 56 | --unsafe-rpc-external \ 57 | --unsafe-force-node-key-generation \ 58 | --rpc-methods=Unsafe \ 59 | --rpc-cors=all \ 60 | $litep2p_param \ 61 | $hw_bench_param \ 62 | --sync=warp \ 63 | $out_peers_param \ 64 | $in_peers_param \ 65 | $node_key_param \ 66 | $name_param \ 67 | $telemetry_url_param \ 68 | $no_telemetry_param \ 69 | $chain_param \ 70 | $public_address_param \ 71 | $local_peer_param 72 | -------------------------------------------------------------------------------- /charts/polkadot-payout/templates/cronjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: CronJob 3 | metadata: 4 | name: polkadot-payout-cron 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | schedule: {{ .Values.cron_schedule }} 8 | concurrencyPolicy: Forbid 9 | jobTemplate: 10 | spec: 11 | template: 12 | metadata: 13 | labels: 14 | app: polkadot-payout-cron 15 | spec: 16 | nodeSelector: 17 | {{ toYaml .Values.node_selector | indent 12 }} 18 | containers: 19 | - name: polkadot-payout-cron 20 | image: {{ .Values.polkadot_k8s_images.polkadot_payout_cron }} 21 | env: 22 | - name: PAYOUT_ACCOUNT_MNEMONIC 23 | valueFrom: 24 | secretKeyRef: 25 | name: polkadot-payout-secrets 26 | key: payout-account-mnemonic 27 | - name: "SLACK_ALERT_TOKEN" 28 | valueFrom: 29 | secretKeyRef: 30 | name: polkadot-payout-secrets 31 | key: slack-alert-token 32 | - name: "STASH_ACCOUNT_ADDRESS" 33 | value: "{{ .Values.stash_account_address }}" 34 | - name: "STASH_ACCOUNT_ALIAS" 35 | value: "{{ .Values.stash_account_alias }}" 36 | - name: "SLACK_ALERT_CHANNEL" 37 | value: "{{ .Values.slack_alert_channel }}" 38 | - name: "NODE_ENDPOINT" 39 | value: "{{ .Values.node_endpoint }}" 40 | - name: "NUM_PAST_ERAS" 41 | value: "{{ .Values.num_past_eras }}" 42 | - name: "PAYOUT_ACCOUNT_ALIAS" 43 | value: "{{ .Values.payout_account_alias }}" 44 | - name: "CHAIN" 45 | value: "{{ .Values.chain }}" 46 | resources: 47 | limits: 48 | cpu: 0 49 | imagePullPolicy: IfNotPresent 50 | restartPolicy: OnFailure 51 | -------------------------------------------------------------------------------- /charts/polkadot-votebot/templates/cronjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: CronJob 3 | metadata: 4 | name: polkadot-votebot-cron 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | schedule: {{ .Values.cron_schedule }} 8 | concurrencyPolicy: Forbid 9 | jobTemplate: 10 | spec: 11 | template: 12 | metadata: 13 | labels: 14 | app: polkadot-votebot-cron 15 | spec: 16 | nodeSelector: 17 | {{ toYaml .Values.node_selector | indent 12 }} 18 | containers: 19 | - name: polkadot-votebot-gov2-cron 20 | image: {{ .Values.polkadot_k8s_images.polkadot_votebot_gov2_cron }} 21 | env: 22 | - name: PROXY_ACCOUNT_MNEMONIC 23 | valueFrom: 24 | secretKeyRef: 25 | name: polkadot-proxy-secrets 26 | key: proxy-account-mnemonic 27 | - name: "SLACK_ALERT_TOKEN" 28 | valueFrom: 29 | secretKeyRef: 30 | name: polkadot-proxy-secrets 31 | key: slack-alert-token 32 | - name: "STASH_ACCOUNT_ADDRESS" 33 | value: "{{ .Values.stash_account_address }}" 34 | - name: "STASH_ACCOUNT_ALIAS" 35 | value: "{{ .Values.stash_account_alias }}" 36 | - name: "SLACK_ALERT_CHANNEL" 37 | value: "{{ .Values.slack_alert_channel }}" 38 | - name: "NODE_ENDPOINT" 39 | value: "{{ .Values.node_endpoint }}" 40 | - name: "VOTE_REPO" 41 | value: "{{ .Values.vote_repo }}" 42 | - name: "PROXY_ACCOUNT_ALIAS" 43 | value: "{{ .Values.proxy_account_alias }}" 44 | - name: "CHAIN" 45 | value: "{{ .Values.chain }}" 46 | resources: 47 | limits: 48 | cpu: 0 49 | imagePullPolicy: IfNotPresent 50 | restartPolicy: OnFailure 51 | -------------------------------------------------------------------------------- /polkadot-session-key-check/index.ts: -------------------------------------------------------------------------------- 1 | /* A script to verify session key. 2 | * Copyright 2022 MIDL.dev 3 | 4 | * All inputs come from environment variables: 5 | * 6 | * * NODE_ENDPOINT : the polkadot/kusama node rpc (localhost) 7 | * * STASH_ACCOUNT_ADDRESS: the address of the validator's stash 8 | * * STASH_ACCOUNT_ALIAS: an alias for your validator 9 | * 10 | * 11 | * To run continously, put the following script in a cronjob. 12 | * See for reference: https://opensource.com/article/17/11/how-use-cron-linux 13 | * */ 14 | 15 | // Import the API 16 | import '@polkadot/types'; 17 | import { ApiPromise, WsProvider } from '@polkadot/api'; 18 | import { WebClient } from '@slack/web-api'; 19 | 20 | async function main() { 21 | const provider = new WsProvider(`ws://${process.env.NODE_ENDPOINT}:9944`); 22 | // Create our API 23 | const api = await ApiPromise.create({ provider }); 24 | 25 | 26 | const stash_account: string = process.env.STASH_ACCOUNT_ADDRESS!; 27 | const stash_alias = process.env.STASH_ACCOUNT_ALIAS; //optional 28 | // https://wiki.polkadot.network/docs/build-ss58-registry 29 | const currentBlockNum = (await api.rpc.chain.getHeader()).number; 30 | 31 | console.log("Polkadot Session Key Verificator by MIDL.dev"); 32 | console.log("Copyright 2022 MIDLDEV OU"); 33 | console.log("***"); 34 | console.log(`Current block number: ${currentBlockNum.toHuman()}`); 35 | console.log(`Stash account address: ${stash_account}`); 36 | console.log(`Stash account alias: ${stash_alias}`); 37 | console.log(`Node RPC endpoint in use: ${process.env.NODE_ENDPOINT}`); 38 | let nextKeys = await api.query.session.nextKeys(stash_account); 39 | console.log(`Node's next keys: ${nextKeys}`); 40 | console.log(`Node's next keys in hex: ${nextKeys.toHex()}`); 41 | let nodeHasKeys = await api.rpc.author.hasSessionKeys(nextKeys.toHex()); 42 | console.log(`Local node has the session keys necessary to validate: ${nodeHasKeys}`); 43 | if (nodeHasKeys.isFalse) { 44 | let message = `Node ${stash_alias} does not have the session keys advertised on-chain in local storage. Expected session key: ${nextKeys.toHex().substring(0, 12)}...`; 45 | console.error(message); 46 | const slackWeb = new WebClient(process.env.SLACK_ALERT_TOKEN!); 47 | await slackWeb.chat.postMessage({ text: message, channel: process.env.SLACK_ALERT_CHANNEL! }) 48 | } 49 | console.log("Exiting"); 50 | process.exit(0); 51 | } 52 | 53 | main().then(console.log).catch(console.error); 54 | -------------------------------------------------------------------------------- /charts/polkadot/values.yaml: -------------------------------------------------------------------------------- 1 | # Images not part of the tezos-k8s repo go here 2 | images: 3 | polkadot_node: "paritytech/polkadot:latest" 4 | # Images that are part of the polkadot-k8s repo go here with 'latest' tag 5 | polkadot_k8s_images: 6 | polkadot_archive_downloader: ghcr.io/midl-dev/polkadot-archive-downloader:master 7 | polkadot_node_key_configurator: ghcr.io/midl-dev/polkadot-node-key-configurator:master 8 | polkadot_sidecar: ghcr.io/midl-dev/polkadot-sidecar:master 9 | polkadot_session_key_check: ghcr.io/midl-dev/polkadot-session-key-check:master 10 | 11 | #polkadot_archive_url: 12 | 13 | # customize telemetry url 14 | polkadot_telemetry_url: null 15 | 16 | # set to true to not upload any telemetry 17 | no_telemetry: false 18 | 19 | polkadot_validator_name: polkadot_k8s_pulumi 20 | 21 | number_of_out_peers: 10 22 | 23 | number_of_in_peers: 10 24 | 25 | # if enabled, will launch a cronjob that alerts you 26 | # when the session key for the validator is not present 27 | # in the local node. 28 | session_key_check: 29 | enabled: false 30 | stash_account_address: "stash account address to verify" 31 | stash_account_alias: "alias for the stash account" 32 | slack_alert_token: "token to send session key mismatch alerts on slack" 33 | slack_alert_channel: "the slack channel where you want to receive the alert" 34 | cron_schedule: "0 */6 * * *" 35 | 36 | chain: kusama 37 | 38 | # list of peers to always connect to. could be polkadot nodes in different namespaces 39 | # should be a list of key-value pairs with the key as namespace name and the value as private network key 40 | local_nodes: {} 41 | 42 | # if provided, this will be passed as the public ip/port combination of the node 43 | # If you have an ingress network load balancer ip sending p2p traffic to the node, set this to its address/port 44 | p2p_ip: null 45 | p2p_port: 30333 46 | 47 | # to deploy in a specific node pool, put label here 48 | node_selector: {} 49 | 50 | # vol size (in Gi) 51 | # Applies to the statefulset's PVC template. 52 | # consequently this value only applies for creation. 53 | # It is not possible to resize the volume by editing this value. 54 | # Instead, you must resize the pvc directly. 55 | vol_size: 50 56 | 57 | # storage class name 58 | # to specify the storage class for polkadot storage backend volume 59 | # storage_class: my-storage-class 60 | 61 | # deploy service monitor? 62 | # only set to true if you have the prometheus operator installed. 63 | # Otherwise, helm installation will fail 64 | deploy_service_monitor: false 65 | 66 | resources: 67 | limits: 68 | cpu: 0 69 | # requests: 70 | # cpu: 100m 71 | # memory: 128Mi 72 | 73 | # liveness probe settings - the polkadot node restarts when not responsive 74 | livenessProbe: 75 | periodSeconds: 30 76 | failureThreshold: 40 77 | 78 | #disable hardware benchmarks 79 | no_hardware_benchmarks: "true" 80 | -------------------------------------------------------------------------------- /polkadot-sidecar/polkadot_sidecar.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request 2 | import requests 3 | import time 4 | 5 | application = Flask(__name__) 6 | 7 | @application.route('/is_synced') 8 | def sync_checker(): 9 | try: 10 | system_health = requests.post('http://127.0.0.1:9944', json={"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}).json()["result"] 11 | 12 | if system_health["isSyncing"]: 13 | err = "Still syncing", 500 14 | print(err) 15 | return err 16 | 17 | current_block_height = requests.post('http://127.0.0.1:9944', json={"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}).json()["result"]["currentBlock"] 18 | 19 | current_block_hash = requests.post('http://127.0.0.1:9944', json={"id":1, "jsonrpc":"2.0", "method": "chain_getBlockHash", "params":[current_block_height]}).json()["result"] 20 | current_block = requests.post('http://127.0.0.1:9944', json={"id":1, "jsonrpc":"2.0", "method": "chain_getBlock", "params":[current_block_hash]}).json()["result"]["block"] 21 | except requests.exceptions.RequestException as e: 22 | err = "Could not connect to node, %s" % repr(e), 500 23 | print(err) 24 | return err 25 | 26 | timestamp_extrinsic = current_block["extrinsics"][0].split("0x")[1] 27 | # take bytes from fourth to end 28 | timestamp = bytes.fromhex(timestamp_extrinsic[10:]) 29 | # bytes are little endian 30 | timestamp_int = int(int.from_bytes(timestamp, "little")/1000) 31 | time_now = int(time.time()) 32 | last_block_age = time_now - timestamp_int 33 | 34 | PROBLEM_DELAY = 180 35 | if last_block_age > PROBLEM_DELAY: 36 | err = f"last block is more than {PROBLEM_DELAY} seconds old", 500 37 | print(err) 38 | return err 39 | return "chain is synced" 40 | 41 | 42 | 43 | # timestamp is encoded with scale codec 44 | # https://substrate.dev/docs/en/knowledgebase/advanced/codec 45 | # from riot discussion 46 | # https://matrix.to/#/!LhjZccBOqFNYKLdmbb:polkadot.builders/$1589987466245024AEJsU:matrix.org?via=matrix.parity.io&via=matrix.org&via=corepaper.org 47 | 48 | # 49 | #nuevax 50 | #it is still unclear to me, the second half of the string always begins with 0b, which indicates an integer, however it does not have the two bits after that indicative for one of the integer formats from the Codec definition. 51 | #Jaco 52 | #0x0b = 0b1011 - 11 (lower 2 bits as per spec) indicates 4 bytes mode, so number of byte following is 4 (as indicated) + 0b10 bytes - so total of 6 bytes. 53 | #nuevax 54 | #I tried all kinds of 6 bytes hex to dec, but to me it seems the 10/13 digit dec timestamp cannot be generated out of 6 bytes even though it says compact. 55 | #nuevax 56 | #Message deleted 57 | #nuevax 58 | #0x280402000bb1f14e327201 this is the string from the extrinsic, 0bb1f14e327201 the second half, after 0b none of the codec specifications. 59 | #Jaco 60 | #:Looks valid, manually decoded it, 61 | # 62 | #1 63 | #2 64 | #console.log(new Date(1589981934001)) 65 | #Wed May 20 2020 15:38:54 GMT+0200 (Central European Summer Time) 66 | -------------------------------------------------------------------------------- /charts/polkadot/templates/statefulset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: StatefulSet 4 | metadata: 5 | name: polkadot-node 6 | namespace: {{ .Release.Namespace }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: polkadot-node 11 | serviceName: polkadot-node 12 | replicas: 1 13 | template: 14 | metadata: 15 | labels: 16 | app: polkadot-node 17 | spec: 18 | nodeSelector: 19 | {{ toYaml .Values.node_selector | indent 8 }} 20 | securityContext: 21 | fsGroup: 1000 22 | containers: 23 | - name: polkadot-node 24 | image: {{ .Values.images.polkadot_node }} 25 | command: 26 | - /bin/bash 27 | args: 28 | - "-c" 29 | - | 30 | {{ tpl (.Files.Get "scripts/polkadot-node.sh") . | indent 12 }} 31 | ports: 32 | - containerPort: 9944 33 | name: dot-rpc-port 34 | - containerPort: 9615 35 | name: metrics 36 | - containerPort: {{ .Values.p2p_port }} 37 | name: dot-p2p-port 38 | volumeMounts: 39 | - name: polkadot-node-pv-claim 40 | mountPath: /polkadot 41 | envFrom: 42 | - configMapRef: 43 | name: polkadot-configmap 44 | resources: 45 | {{ toYaml .Values.resources | indent 10 }} 46 | imagePullPolicy: IfNotPresent 47 | readinessProbe: 48 | periodSeconds: 30 49 | timeoutSeconds: 10 50 | httpGet: 51 | path: /is_synced 52 | port: 31764 53 | livenessProbe: 54 | # kill container after 20 minutes unsynced 55 | # that's enough time to not be chilled on kusama 56 | periodSeconds: {{ .Values.livenessProbe.periodSeconds }} 57 | failureThreshold: {{ .Values.livenessProbe.failureThreshold }} 58 | timeoutSeconds: 10 59 | httpGet: 60 | path: /is_synced 61 | port: 31764 62 | startupProbe: 63 | # wait for initial sync 64 | periodSeconds: 30 65 | failureThreshold: 1440 66 | timeoutSeconds: 10 67 | httpGet: 68 | path: /is_synced 69 | port: 31764 70 | - name: polkadot-sidecar 71 | image: {{ .Values.polkadot_k8s_images.polkadot_sidecar }} 72 | resources: 73 | limits: 74 | cpu: 0 75 | imagePullPolicy: Always 76 | initContainers: 77 | - name: polkadot-node-key-configurator 78 | image: {{ .Values.polkadot_k8s_images.polkadot_node_key_configurator }} 79 | volumeMounts: 80 | - name: polkadot-node-pv-claim 81 | mountPath: /polkadot 82 | - name: polkadot-node-keys 83 | mountPath: /polkadot-node-keys 84 | envFrom: 85 | - configMapRef: 86 | name: polkadot-configmap 87 | imagePullPolicy: Always 88 | resources: 89 | limits: 90 | cpu: 0 91 | - name: polkadot-archive-downloader 92 | image: {{ .Values.polkadot_k8s_images.polkadot_archive_downloader }} 93 | volumeMounts: 94 | - name: polkadot-node-pv-claim 95 | mountPath: /polkadot 96 | env: 97 | - name: CHAIN 98 | valueFrom: 99 | configMapKeyRef: 100 | name: polkadot-configmap 101 | key: CHAIN 102 | - name: ARCHIVE_URL 103 | valueFrom: 104 | configMapKeyRef: 105 | name: polkadot-configmap 106 | key: ARCHIVE_URL 107 | imagePullPolicy: Always 108 | resources: 109 | limits: 110 | cpu: 0 111 | volumes: 112 | - name: polkadot-node-keys 113 | secret: 114 | secretName: polkadot-node-keys 115 | volumeClaimTemplates: 116 | - metadata: 117 | name: polkadot-node-pv-claim 118 | spec: 119 | accessModes: [ "ReadWriteOnce" ] 120 | {{- if hasKey .Values "storage_class" }} 121 | storageClassName: {{ .Values.storage_class }} 122 | {{- end }} 123 | resources: 124 | requests: 125 | storage: {{ .Values.vol_size }}Gi 126 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - "**" 7 | pull_request: 8 | release: 9 | types: [created] 10 | 11 | jobs: 12 | 13 | list_containers_to_publish: 14 | # based on 15 | # https://stackoverflow.com/a/62953566/207209 16 | runs-on: ubuntu-latest 17 | outputs: 18 | matrix: ${{ steps.gen-containers-matrix.outputs.matrix }} 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - id: gen-containers-matrix 23 | run: | 24 | container_list=$(jq -c -n --arg cont "$(find -name 'Dockerfile' -printf '%h\n' | sort -u | sed 's/.\///')" '{ container: $cont | split("\n")}') 25 | echo "Dynamically generated container list based on subdirectories of the repo with a dockerfile in it. The following list will be passed to next build step:" 26 | echo $container_list 27 | echo "::set-output name=matrix::$container_list" 28 | 29 | publish_containers: 30 | # based on 31 | # https://github.com/docker/build-push-action#usage 32 | runs-on: ubuntu-latest 33 | needs: list_containers_to_publish 34 | strategy: 35 | matrix: ${{fromJson(needs.list_containers_to_publish.outputs.matrix)}} 36 | 37 | steps: 38 | - name: Checkout 39 | uses: actions/checkout@v2 40 | 41 | - name: Login to registry 42 | run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin 43 | - name: Docker meta 44 | id: meta 45 | uses: docker/metadata-action@v4 46 | with: 47 | images: ghcr.io/${{ github.repository_owner }}/${{ matrix.container }} 48 | tags: | 49 | type=ref,event=branch 50 | type=ref,event=pr 51 | type=match,pattern=v(.*),group=1 52 | 53 | - name: Push to GHCR 54 | uses: docker/build-push-action@v2 55 | with: 56 | context: ${{ matrix.container }}/. 57 | file: ${{ matrix.container }}/Dockerfile 58 | push: true 59 | tags: ${{ steps.meta.outputs.tags }} 60 | labels: ${{ steps.meta.outputs.labels }} 61 | 62 | lint_helm_charts: 63 | runs-on: ubuntu-latest 64 | steps: 65 | - name: Checkout 66 | uses: actions/checkout@v2 67 | 68 | - name: Set up Helm 69 | uses: azure/setup-helm@v1 70 | with: 71 | version: v3.4.2 72 | 73 | - name: Lint Helm Charts 74 | run: helm lint charts/* 75 | 76 | publish_helm_charts: 77 | runs-on: ubuntu-latest 78 | needs: [lint_helm_charts, publish_containers] 79 | if: github.event_name == 'release' && github.event.action == 'created' 80 | steps: 81 | - name: Checkout 82 | uses: actions/checkout@v2 83 | 84 | - name: Install yq 85 | run: | 86 | sudo wget -q https://github.com/mikefarah/yq/releases/download/v4.2.0/yq_linux_amd64 -O /usr/bin/yq 87 | sudo chmod +x /usr/bin/yq 88 | 89 | - name: Get Release Version 90 | id: get_release_version 91 | run: echo "::set-output name=RELEASE_VERSION::${GITHUB_REF/refs\/tags\//}" 92 | 93 | - name: Set Helm Chart and Image Versions 94 | run: | 95 | set -x 96 | 97 | RELEASE_VERSION=${{ steps.get_release_version.outputs.RELEASE_VERSION }} 98 | 99 | for chart in charts/*; do 100 | [[ ! -d "$chart" ]] && continue 101 | echo $chart 102 | 103 | # Update Chart.yaml with release version 104 | yq e ".version = \"$RELEASE_VERSION\"" -i "$chart/Chart.yaml" 105 | 106 | # Get midl-dev/polkadot-k8s images specified in values.yaml 107 | custom_images=$(yq e '(.polkadot_k8s_images[]) | path | .[-1]' "$chart/values.yaml") 108 | 109 | # Update the release version of each of polkadot-k8s images 110 | for image in $custom_images; do 111 | image_name=$(yq e ".polkadot_k8s_images.$image" $chart/values.yaml | sed -E "s/ghcr.io\/midl-dev\/polkadot-(.*):.*/\1/") 112 | yq e ".polkadot_k8s_images.$image = \"ghcr.io/midl-dev/polkadot-$image_name:$(echo $RELEASE_VERSION | sed s/v//)\"" -i $chart/values.yaml 113 | done 114 | done 115 | 116 | - name: Publish Helm charts 117 | uses: stefanprodan/helm-gh-pages@master 118 | with: 119 | linting: off # We already linted in a job before 120 | token: ${{ secrets.GITHUB_TOKEN }} 121 | branch: gh-pages 122 | -------------------------------------------------------------------------------- /polkadot-payout-cron/src/index.ts: -------------------------------------------------------------------------------- 1 | /* A simple one-shot payout script for Polkadot 2 | * Copyright 2022 MIDL.dev 3 | * 4 | * This script requires a payout account with dust money to pay for transaction fees to call the payout extrinsic. 5 | * 6 | * ######################################################## 7 | * ## ## 8 | * ## Want a simpler solution ? ## 9 | * ## ## 10 | * ## https://MIDL.dev/polkadot-automated-payouts ## 11 | * ## ## 12 | * ## Kusama automated payouts for US$9.99 / month ## 13 | * ## Polkadot automated payouts for US$19.99 / month ## 14 | * ## ## 15 | * ######################################################## 16 | * 17 | * All inputs come from environment variables: 18 | * 19 | * * NODE_ENDPOINT : the polkadot/kusama node rpc (localhost) 20 | * * PAYOUT_ACOUNT_MNEMONIC: 12 words of the payout account (should have little balance, just for fees) 21 | * * STASH_ACCOUNT_ADDRESS: the address of the validator's stash 22 | * * STASH_ACCOUNT_ALIAS: an alias for your validator 23 | * * NUM_PAST_ERAS: how many eras in the past to check for unpaid rewards 24 | * 25 | * The script queries the current era. It then verifies that: 26 | * 27 | * * the previous era has not been paid yet 28 | * * the validator was active in the previous era 29 | * 30 | * When these conditions are met, it sends the payout extrinsic and exits. 31 | * 32 | * If payout extrinsic fails, it will post an error to the console and to Slack 33 | * if the SLACK_ALERT_TOKEN and SLACK_ALERT_CHANNEL env vars are set. 34 | * 35 | * This script does not support multiple validators. To support multiple validators, run several cronjobs. 36 | * 37 | * Payout for multiple eras in the past is supported, but will throw an error. 38 | * This script is expected to run at least once per era. 39 | * 40 | * To run once: 41 | * export NODE_ENDPOINT=localhost 42 | * export PAYOUT_ACCOUNT_MNEMONIC="your twelve key words..." 43 | * export STASH_ACCOUNT_ADDRESS="GyrcqNwF87LFc4BRxhxakq8GZRVNzhGn3NLfSQhVHQxqYYx" 44 | * export STASH_ACCOUNT_ALIAS="my awesome validator" 45 | * export NUM_PAST_ERAS=5 46 | * node index.js 47 | * 48 | * To run continously, put the following script in a cronjob. 49 | * See for reference: https://opensource.com/article/17/11/how-use-cron-linux 50 | * */ 51 | 52 | // Import the API 53 | import { ApiPromise, WsProvider } from '@polkadot/api'; 54 | import { Keyring, encodeAddress } from '@polkadot/keyring'; 55 | import { WebClient } from '@slack/web-api'; 56 | import '@polkadot/api-augment/kusama'; 57 | import '@polkadot/types'; 58 | 59 | async function sendErrorToSlackAndExit(message: string, exitWithFailure: boolean = true) { 60 | console.error(message); 61 | if (process.env.SLACK_ALERT_TOKEN) { 62 | const slackWeb = new WebClient(process.env.SLACK_ALERT_TOKEN!); 63 | await slackWeb.chat.postMessage({ text: message, channel: process.env.SLACK_ALERT_CHANNEL! }) 64 | } 65 | const exitCode = exitWithFailure ? 1 : 0; 66 | process.exit(exitCode) 67 | } 68 | async function main() { 69 | const provider = new WsProvider(`ws://${process.env.NODE_ENDPOINT!}:9944`); 70 | // Create our API 71 | const api = await ApiPromise.create({ provider }); 72 | 73 | // Constuct the keying 74 | const keyring = new Keyring({ type: 'sr25519' }); 75 | 76 | // Add the payout account to our keyring 77 | const payoutKey = keyring.addFromUri(process.env.PAYOUT_ACCOUNT_MNEMONIC!); 78 | 79 | const activeEra = (await api.query.staking.activeEra()).unwrapOrDefault() 80 | 81 | 82 | const stash_account = process.env.STASH_ACCOUNT_ADDRESS!; 83 | const stash_alias = process.env.STASH_ACCOUNT_ALIAS!; //optional 84 | const payout_alias = process.env.PAYOUT_ACCOUNT_ALIAS!; //optional 85 | const num_past_eras = parseInt(process.env.NUM_PAST_ERAS!); 86 | const chain = process.env.CHAIN; 87 | // https://wiki.polkadot.network/docs/build-ss58-registry 88 | const chain_ss58_prefix = (chain == "kusama") ? 2 : 0 89 | const payout_account = encodeAddress(payoutKey.address, chain_ss58_prefix); 90 | 91 | console.log(`Chain ${chain}`); 92 | console.log(`Stash account address ${stash_account}`); 93 | console.log(`Stash account alias ${stash_alias}`); 94 | console.log(`Payout account address ${payout_account}`); 95 | console.log(`Payout account alias ${payout_alias}`); 96 | console.log(`Number of past eras to pay out ${num_past_eras}`); 97 | console.log(`Node RPC endpoint in use ${process.env.NODE_ENDPOINT}`); 98 | 99 | // list of error codes that would allow the job to exit without failure 100 | const exitWithoutFailureErrorCodes: number[] = [1010]; 101 | 102 | console.log(`Active Era is ${activeEra}`) 103 | 104 | let erasToClaim = []; 105 | for (let i = 0; i < num_past_eras; i++) { 106 | let eraToClaim = activeEra.index.toNumber() - i - 1; 107 | let exposed = !(await api.query.staking.erasStakersOverview(eraToClaim, stash_account)).isNone; 108 | 109 | if (exposed) { 110 | let claimed = (await api.query.staking.claimedRewards(eraToClaim, stash_account)).length > 0; 111 | if (!claimed) { 112 | console.log(`Outstanding rewards found for validator for ${eraToClaim}.`) 113 | erasToClaim.push(eraToClaim); 114 | } else { 115 | console.log(`Rewards already claimed for era ${eraToClaim}, no payout will be made`); 116 | } 117 | } else { 118 | console.log(`Validator was not in active set for era ${eraToClaim}, no payout will be made`); 119 | } 120 | } 121 | 122 | if (erasToClaim.length > 0) { 123 | if (erasToClaim.length > 1) { 124 | var message = `Warning: Found and paid payouts more than one era in the past: eras ${erasToClaim} for validator ${stash_alias}. Payout bot should run at least once per era. Please check your payout engine.`; 125 | if (process.env.SLACK_ALERT_TOKEN) { 126 | const slackWeb = new WebClient(process.env.SLACK_ALERT_TOKEN); 127 | await slackWeb.chat.postMessage({ text: message, channel: process.env.SLACK_ALERT_CHANNEL! }); 128 | } 129 | console.warn(message); 130 | } 131 | 132 | console.log(`Issuing payoutStakers extrinsic from address ${payout_alias} for validator stash ${stash_alias} for era ${erasToClaim[0]}`); 133 | 134 | try { 135 | await api.tx.staking.payoutStakers(stash_account, erasToClaim[0]).signAndSend(payoutKey, (async (result) => { 136 | let status = result.status; 137 | let events = result.events; 138 | console.log('Transaction status:', result.status.type); 139 | 140 | if (status.isInBlock) { 141 | console.log('Included at block hash', result.status.asInBlock.toHex()); 142 | 143 | events.forEach((event: any) => { 144 | console.log('\t', event.toString()); 145 | }); 146 | } else if (status.isFinalized) { 147 | console.log('Finalized block hash', status.asFinalized.toHex()); 148 | if (result.dispatchError) { 149 | let slackMessage = `Payout extrinsic was succesfully finalized on-chain but failed for validator ${stash_alias} (${stash_account}) with error ${status.asFinalized.toHex()}.`; 150 | sendErrorToSlackAndExit(slackMessage) 151 | } else { 152 | console.log("extrinsic success in finalized block, exiting") 153 | process.exit(0); 154 | } 155 | } else if (status.isInvalid || status.isDropped) { 156 | let slackMessage = `Payout extrinsic failed for validator ${stash_alias}(${stash_account}) with error ${status}.`; 157 | sendErrorToSlackAndExit(slackMessage); 158 | } else if (status.isRetracted) { 159 | // fail the job but do not alert. It is likely the transaction will go through at next try. 160 | process.exit(1) 161 | } 162 | })); 163 | } 164 | catch (e: any) { 165 | const error_message: string = e.message 166 | const exitWithFaiilure = exitWithoutFailureErrorCodes.indexOf(e.code) < 0 ? true : false 167 | let slackMessage = `Payout extrinsic failed on-chain submission for validator ${stash_alias} from payout address ${payout_alias}(\`${payout_account}\`) with error ${error_message}.`; 168 | sendErrorToSlackAndExit(slackMessage, exitWithFaiilure); 169 | } 170 | } else { 171 | console.log("Exiting"); 172 | process.exit(0); 173 | } 174 | 175 | } 176 | 177 | main().catch(console.error); 178 | -------------------------------------------------------------------------------- /polkadot-payout-cron/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | /* Projects */ 5 | // "incremental": true, /* Enable incremental compilation */ 6 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 7 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 8 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 9 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 10 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 11 | /* Language and Environment */ 12 | "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 13 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 14 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 15 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 16 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 17 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 18 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 19 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 20 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 21 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 22 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 23 | /* Modules */ 24 | "module": "commonjs", /* Specify what module code is generated. */ 25 | // "rootDir": "./", /* Specify the root folder within your source files. */ 26 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 27 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 28 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 29 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 30 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 31 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 32 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 33 | // "resolveJsonModule": true, /* Enable importing .json files */ 34 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 35 | /* JavaScript Support */ 36 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 37 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 38 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 39 | /* Emit */ 40 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 41 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 42 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 43 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 44 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 45 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 46 | "outDir": "./build", 47 | // "removeComments": true, /* Disable emitting comments. */ 48 | // "noEmit": true, /* Disable emitting files from a compilation. */ 49 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 50 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 51 | "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 52 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 53 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 54 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 55 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 56 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 57 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 58 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 59 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 60 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 61 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 62 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 63 | /* Interop Constraints */ 64 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 65 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 66 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 67 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 68 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 69 | /* Type Checking */ 70 | "strict": true, /* Enable all strict type-checking options. */ 71 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 72 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 73 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 74 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 75 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 76 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 77 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 78 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 79 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 80 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 81 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 82 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 83 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 84 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 85 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 86 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 87 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 88 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 89 | /* Completeness */ 90 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 91 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 92 | }, 93 | "include": [ 94 | "./src/**/*" 95 | ] 96 | } 97 | -------------------------------------------------------------------------------- /polkadot-session-key-check/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs", /* Specify what module code is generated. */ 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 36 | // "resolveJsonModule": true, /* Enable importing .json files */ 37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 38 | 39 | /* JavaScript Support */ 40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 43 | 44 | /* Emit */ 45 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 46 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 50 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 51 | // "removeComments": true, /* Disable emitting comments. */ 52 | // "noEmit": true, /* Disable emitting files from a compilation. */ 53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 55 | "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 61 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 66 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 67 | 68 | /* Interop Constraints */ 69 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 70 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 71 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 72 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 73 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 74 | 75 | /* Type Checking */ 76 | "strict": true, /* Enable all strict type-checking options. */ 77 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 78 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 79 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 80 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 81 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 82 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 83 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 84 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 85 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 86 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 87 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 88 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 89 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 90 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 91 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 92 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 93 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 94 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 95 | 96 | /* Completeness */ 97 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 98 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /polkadot-votebot-gov2-cron/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs", /* Specify what module code is generated. */ 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 36 | // "resolveJsonModule": true, /* Enable importing .json files */ 37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 38 | 39 | /* JavaScript Support */ 40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 43 | 44 | /* Emit */ 45 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 46 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 50 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 51 | // "removeComments": true, /* Disable emitting comments. */ 52 | // "noEmit": true, /* Disable emitting files from a compilation. */ 53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 55 | "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 61 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 66 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 67 | 68 | /* Interop Constraints */ 69 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 70 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 71 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 72 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 73 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 74 | 75 | /* Type Checking */ 76 | "strict": true, /* Enable all strict type-checking options. */ 77 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 78 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 79 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 80 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 81 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 82 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 83 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 84 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 85 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 86 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 87 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 88 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 89 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 90 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 91 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 92 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 93 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 94 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 95 | 96 | /* Completeness */ 97 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 98 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /polkadot-votebot-gov2-cron/index.ts: -------------------------------------------------------------------------------- 1 | /* A simple one-shot voteBot script for Polkadot 2 | * Copyright 2024 MIDL.dev 3 | 4 | * All inputs come from environment variables: 5 | * 6 | * * NODE_ENDPOINT : the polkadot/kusama node rpc (localhost) 7 | * * PROXY_ACOUNT_MNEMONIC: 12 words of the account for which the stash has delegated Governance rights via proxy (should have little balance, just for fees) 8 | * * STASH_ACCOUNT_ADDRESS: the address of the validator's stash 9 | * * STASH_ACCOUNT_ALIAS: an alias for your validator 10 | * * VOTE_REPO: the github repository where your vote choices are kept in yaml format, for example midl-dev/dotsama-votes 11 | * 12 | * The script queries the current referendums, then try to vote for the oldest unvoted referendum. 13 | * 14 | * If there is no unvoted referendum, it queries the expired referenda. If there are any, it removes the votes. 15 | * 16 | * If voting extrinsic fails, it will post an error to the console and to Slack 17 | * 18 | * To run continously, put the following script in a cronjob. 19 | * See for reference: https://opensource.com/article/17/11/how-use-cron-linux 20 | * */ 21 | 22 | // Import the API 23 | import '@polkadot/api-augment/kusama'; 24 | import '@polkadot/types'; 25 | import { ApiPromise, WsProvider } from '@polkadot/api'; 26 | import { Keyring, encodeAddress } from '@polkadot/keyring'; 27 | import { WebClient } from '@slack/web-api'; 28 | 29 | const yaml = require('js-yaml'); 30 | const fs = require('fs'); 31 | const request = require('request'); 32 | 33 | async function sendErrorToSlackAndExit(message: string, exitWithFailure: boolean = true) { 34 | console.error(message); 35 | if (process.env.SLACK_ALERT_TOKEN) { 36 | const slackWeb = new WebClient(process.env.SLACK_ALERT_TOKEN!); 37 | await slackWeb.chat.postMessage({ text: message, channel: process.env.SLACK_ALERT_CHANNEL! }) 38 | } 39 | const exitCode = exitWithFailure ? 1 : 0; 40 | process.exit(exitCode); 41 | } 42 | 43 | async function main() { 44 | const provider = new WsProvider(`ws://${process.env.NODE_ENDPOINT}:9944`); 45 | // Create our API 46 | const api = await ApiPromise.create({ provider }); 47 | 48 | // Constuct the keying 49 | const keyring = new Keyring({ type: 'sr25519' }); 50 | 51 | // Add the voteBot account to our keyring 52 | const voteBotKey = keyring.addFromUri(process.env.PROXY_ACCOUNT_MNEMONIC!); 53 | 54 | const stash_account: string = process.env.STASH_ACCOUNT_ADDRESS!; 55 | const stash_alias = process.env.STASH_ACCOUNT_ALIAS; //optional 56 | const vote_bot_alias = process.env.PROXY_ACCOUNT_ALIAS; //optional 57 | const chain = process.env.CHAIN; 58 | // https://wiki.polkadot.network/docs/build-ss58-registry 59 | const chain_ss58_prefix = (chain == "kusama") ? 2 : 0 60 | const voteBot_account = encodeAddress(voteBotKey.address, chain_ss58_prefix); 61 | const stash_account_address = encodeAddress(stash_account, chain_ss58_prefix); 62 | const voteBalance = (await api.query.system.account(stash_account_address)).data.free.toBigInt() - BigInt(100000000); 63 | const currentBlockNum = (await api.rpc.chain.getHeader()).number; 64 | 65 | // will send an alert when the referendum is this close to finishing, and 66 | // recommendation still hasn't been committed to the repo. 67 | const DEADLINE_WARNING_NUM_BLOCKS: BigInt = BigInt(15000); 68 | 69 | console.log("Polkadot Vote Bot by MIDL.dev"); 70 | console.log("Copyright 2023 MIDLDEV OU"); 71 | console.log("***"); 72 | console.log(`Chain: ${chain}`); 73 | console.log(`Current block number: ${currentBlockNum.toHuman()}`); 74 | console.log(`Stash account address: ${stash_account}`); 75 | console.log(`Stash account alias: ${stash_alias}`); 76 | console.log(`Voting proxy account address: ${voteBot_account}`); 77 | console.log(`Voting proxy account alias: ${vote_bot_alias}`); 78 | console.log(`Vote balance in nanodot: ${voteBalance.toString()}`); 79 | console.log(`Node RPC endpoint in use: ${process.env.NODE_ENDPOINT}`); 80 | 81 | // list of error codes that would allow the job to exit without failure 82 | const exitWithoutFailureErrorCodes: number[] = [1010]; 83 | 84 | let valVotes: number[] = []; 85 | 86 | const govTracks = api.consts.referenda.tracks; 87 | let classOfValVotes: { [key: number]: any } = {} 88 | for (const govTrackEntry of govTracks) { 89 | let rawValVotes: number[] = await api.query.convictionVoting.votingFor(stash_account_address, govTrackEntry[0]).then(q => JSON.parse(JSON.stringify(q))["casting"]["votes"].map((v: any) => v[0])) 90 | console.log(`Existing votes for track ${govTrackEntry[0]} (${govTrackEntry[1]["name"]}): ${rawValVotes}`) 91 | rawValVotes.forEach((v: number) => { 92 | classOfValVotes[v] = govTrackEntry[0].toNumber() 93 | valVotes.push(v) 94 | }) 95 | } 96 | // TODO: grab the duration per gov track, the estimated time before finishing for every referendum, 97 | // send a slack alert when a referendum is set to expire 98 | 99 | let refCount = await api.query.referenda.referendumCount(); 100 | var referenda: any = []; 101 | let ongoingRefs: any[] = []; 102 | let i: number = refCount.toNumber(); 103 | let trigger = 0; 104 | if (i) { 105 | while (true) { 106 | i = i - 1; 107 | if (i == 0) { 108 | break; 109 | } 110 | var rawR = await api.query.referenda.referendumInfoFor(i); 111 | let r = JSON.parse(JSON.stringify(rawR)); 112 | 113 | if ("ongoing" in r) { 114 | r["number"] = i; 115 | ongoingRefs.push(i); 116 | if (valVotes.includes(i)) { 117 | console.log(`Validator ${stash_alias} has already voted for current referendum ${i}.`); 118 | } else { 119 | console.log(`Validator ${stash_alias} must vote for current referendum ${i}.`); 120 | referenda.push(r); 121 | } 122 | trigger = 0; 123 | } else { 124 | trigger += 1; 125 | if (trigger > 5) { 126 | // assuming that if we see 5 completed referedums in a row, we are done (empirical) 127 | break; 128 | } 129 | } 130 | } 131 | } 132 | 133 | // Load votes from external file 134 | const url = `https://raw.githubusercontent.com/${process.env.VOTE_REPO}/main/${chain}-gov2.yaml`; 135 | const getVotes = (url: string) => { 136 | return new Promise((resolve, reject) => { 137 | request.get(url, (error: any, response: any, body: any) => { 138 | if (!error && response.statusCode == 200) { 139 | return resolve(body); 140 | } 141 | return reject({ 142 | message: "Invalid URL!", 143 | stack: error ? error.stack : null 144 | }); 145 | }); 146 | }); 147 | } 148 | const votes = yaml.load(await getVotes(url)); 149 | 150 | let attemptDeletion: boolean = false; 151 | if (referenda.length == 0) { 152 | console.log("All up-to-date with voting.") 153 | attemptDeletion = true; 154 | } else { 155 | let r = referenda[referenda.length - 1]; 156 | if (!(r["number"] in votes)) { 157 | let errorMsg = `Recommendation for gov2 vote ${r["number"]} has not yet been committed to ${url}. Please commit a recommendation.`; 158 | console.error(errorMsg); 159 | attemptDeletion = true; 160 | } else { 161 | i = r["number"]; 162 | console.log(`Voting ${votes[i]["vote"]} for referendum ${i}. Reason:`); 163 | console.log(votes[i]["reason"]); 164 | let isAye: boolean = (votes[i]["vote"] == "aye" || votes[i]["vote"] == "yay"); 165 | 166 | let vote = { 167 | Standard: { 168 | vote: { 169 | aye: isAye, 170 | conviction: 'None', 171 | }, 172 | balance: voteBalance, 173 | } 174 | }; 175 | console.log(`IsAye ${isAye}`); 176 | 177 | try { 178 | await api.tx.proxy.proxy(stash_account, "Governance", api.tx.convictionVoting.vote(i, vote)).signAndSend(voteBotKey, (async (result) => { 179 | let status = result.status; 180 | let events = result.events; 181 | console.log('Transaction status:', result.status.type); 182 | 183 | if (status.isInBlock) { 184 | console.log('Included at block hash', result.status.asInBlock.toHex()); 185 | 186 | events.forEach((event: any) => { 187 | console.log('\t', event.toString()); 188 | }); 189 | } else if (status.isFinalized) { 190 | console.log('Finalized block hash', status.asFinalized.toHex()); 191 | if (result.dispatchError) { 192 | let slackMessage = `Gov2 Vote extrinsic failed on-chain submission for validator ${stash_alias} from vote address ${vote_bot_alias}(\`${voteBot_account}\`) with error ${result.dispatchError}, check subscan, txhash ${status.asFinalized.toHex()}`; 193 | sendErrorToSlackAndExit(slackMessage) 194 | } else { 195 | console.log("extrinsic success in finalized block, exiting") 196 | process.exit(0); 197 | } 198 | } else if (status.isInvalid || status.isDropped) { 199 | let slackMessage = `Gov2 Vote extrinsic failed for validator ${stash_alias}(${stash_account}) with error ${status}.`; 200 | sendErrorToSlackAndExit(slackMessage); 201 | } else if (status.isRetracted) { 202 | // fail the job but do not alert. It is likely the transaction will go through at next try. 203 | process.exit(1) 204 | } 205 | })); 206 | } catch (e: any) { 207 | const error_message: string = e.message 208 | // If the error code not in exitWithoutFailureErrorCodes, exit with failure. 209 | const exitWithFaiilure = exitWithoutFailureErrorCodes.indexOf(e.code) < 0 ? true : false 210 | const slackMessage = `Gov2 Vote extrinsic failed on - chain submission for validator ${stash_alias} from vote address ${vote_bot_alias}(\`${voteBot_account}\`) with error ${error_message}.` 211 | sendErrorToSlackAndExit(slackMessage, exitWithFaiilure) 212 | } 213 | } 214 | } 215 | 216 | if (attemptDeletion) { 217 | if (valVotes.length > 0) { 218 | console.log("Checking for expired referenda to remove..."); 219 | console.log(`ValVotes: ${valVotes} `) 220 | console.log(`ongoingRefs: ${ongoingRefs} `) 221 | let oldVote: number | undefined; 222 | // Lazily removing one old vote (starting with oldest), so democracy bond can be unlocked easily if needed. 223 | valVotes.forEach(e => { 224 | if (!ongoingRefs.includes(e)) { 225 | oldVote = e; 226 | } 227 | }) 228 | if (oldVote) { 229 | console.log(`Now attempting to remove vote for referendum ${oldVote} of class ${classOfValVotes[oldVote!]}, since referendum has expired. Exit immediately after sending extrinsic without catching any failures.`) 230 | try { 231 | await api.tx.proxy.proxy(stash_account, "Governance", api.tx.convictionVoting.removeVote(classOfValVotes[oldVote!], oldVote!)).signAndSend(voteBotKey, (async (result) => { 232 | console.log('Transaction status:', result.status.type); 233 | let status = result.status; 234 | if (status.isInBlock) { 235 | console.log('Included at block hash', result.status.asInBlock.toHex()); 236 | process.exit(0); 237 | } 238 | })) 239 | } 240 | catch (e: any) { 241 | // exit without any failures for all errors, just post to slack 242 | const exitWithFaiilure = false; 243 | const error_message: string = e.message; 244 | let slackMessage = `Gov2 Vote extrinsic failed on - chain submission for validator ${stash_alias} from vote address ${vote_bot_alias}(\`${voteBot_account}\`) with error ${error_message}.`; 245 | sendErrorToSlackAndExit(slackMessage, exitWithFaiilure); 246 | } 247 | } else { 248 | console.log("No expired referenda, exiting.") 249 | process.exit(0); 250 | } 251 | } else { 252 | console.log("No expired referenda, exiting.") 253 | process.exit(0); 254 | } 255 | } 256 | } 257 | 258 | main().then(console.log).catch(console.error); 259 | -------------------------------------------------------------------------------- /polkadot-payout-cron/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@noble/curves@^1.3.0": 6 | version "1.4.0" 7 | resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz" 8 | integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== 9 | dependencies: 10 | "@noble/hashes" "1.4.0" 11 | 12 | "@noble/hashes@^1.3.1", "@noble/hashes@^1.3.3", "@noble/hashes@1.4.0": 13 | version "1.4.0" 14 | resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz" 15 | integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== 16 | 17 | "@polkadot-api/json-rpc-provider-proxy@0.0.1": 18 | version "0.0.1" 19 | resolved "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.0.1.tgz" 20 | integrity sha512-gmVDUP8LpCH0BXewbzqXF2sdHddq1H1q+XrAW2of+KZj4woQkIGBRGTJHeBEVHe30EB+UejR1N2dT4PO/RvDdg== 21 | 22 | "@polkadot-api/json-rpc-provider@0.0.1": 23 | version "0.0.1" 24 | resolved "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1.tgz" 25 | integrity sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA== 26 | 27 | "@polkadot-api/metadata-builders@0.0.1": 28 | version "0.0.1" 29 | resolved "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.0.1.tgz" 30 | integrity sha512-GCI78BHDzXAF/L2pZD6Aod/yl82adqQ7ftNmKg51ixRL02JpWUA+SpUKTJE5MY1p8kiJJIo09P2um24SiJHxNA== 31 | dependencies: 32 | "@polkadot-api/substrate-bindings" "0.0.1" 33 | "@polkadot-api/utils" "0.0.1" 34 | 35 | "@polkadot-api/observable-client@0.1.0": 36 | version "0.1.0" 37 | resolved "https://registry.npmjs.org/@polkadot-api/observable-client/-/observable-client-0.1.0.tgz" 38 | integrity sha512-GBCGDRztKorTLna/unjl/9SWZcRmvV58o9jwU2Y038VuPXZcr01jcw/1O3x+yeAuwyGzbucI/mLTDa1QoEml3A== 39 | dependencies: 40 | "@polkadot-api/metadata-builders" "0.0.1" 41 | "@polkadot-api/substrate-bindings" "0.0.1" 42 | "@polkadot-api/substrate-client" "0.0.1" 43 | "@polkadot-api/utils" "0.0.1" 44 | 45 | "@polkadot-api/substrate-bindings@0.0.1": 46 | version "0.0.1" 47 | resolved "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.0.1.tgz" 48 | integrity sha512-bAe7a5bOPnuFVmpv7y4BBMRpNTnMmE0jtTqRUw/+D8ZlEHNVEJQGr4wu3QQCl7k1GnSV1wfv3mzIbYjErEBocg== 49 | dependencies: 50 | "@noble/hashes" "^1.3.1" 51 | "@polkadot-api/utils" "0.0.1" 52 | "@scure/base" "^1.1.1" 53 | scale-ts "^1.6.0" 54 | 55 | "@polkadot-api/substrate-client@0.0.1": 56 | version "0.0.1" 57 | resolved "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.0.1.tgz" 58 | integrity sha512-9Bg9SGc3AwE+wXONQoW8GC00N3v6lCZLW74HQzqB6ROdcm5VAHM4CB/xRzWSUF9CXL78ugiwtHx3wBcpx4H4Wg== 59 | 60 | "@polkadot-api/utils@0.0.1": 61 | version "0.0.1" 62 | resolved "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.0.1.tgz" 63 | integrity sha512-3j+pRmlF9SgiYDabSdZsBSsN5XHbpXOAce1lWj56IEEaFZVjsiCaxDOA7C9nCcgfVXuvnbxqqEGQvnY+QfBAUw== 64 | 65 | "@polkadot/api-augment@11.2.1": 66 | version "11.2.1" 67 | resolved "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-11.2.1.tgz" 68 | integrity sha512-Huo457lCqeavbrf1O/2qQYGNFWURLXndW4vNkj8AP+I757WIqebhc6K3+mz+KoV1aTsX/qwaiEgeoTjrrIwcqA== 69 | dependencies: 70 | "@polkadot/api-base" "11.2.1" 71 | "@polkadot/rpc-augment" "11.2.1" 72 | "@polkadot/types" "11.2.1" 73 | "@polkadot/types-augment" "11.2.1" 74 | "@polkadot/types-codec" "11.2.1" 75 | "@polkadot/util" "^12.6.2" 76 | tslib "^2.6.2" 77 | 78 | "@polkadot/api-base@11.2.1": 79 | version "11.2.1" 80 | resolved "https://registry.npmjs.org/@polkadot/api-base/-/api-base-11.2.1.tgz" 81 | integrity sha512-lVYTHQf8S4rpOJ9d1jvQjviHLE6zljl13vmgs+gXHGJwMAqhhNwKY3ZMQW/u/bRE2uKk0cAlahtsRtiFpjHAfw== 82 | dependencies: 83 | "@polkadot/rpc-core" "11.2.1" 84 | "@polkadot/types" "11.2.1" 85 | "@polkadot/util" "^12.6.2" 86 | rxjs "^7.8.1" 87 | tslib "^2.6.2" 88 | 89 | "@polkadot/api-derive@11.2.1": 90 | version "11.2.1" 91 | resolved "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-11.2.1.tgz" 92 | integrity sha512-ts6D6tXmvhBpHDT7E03TStXfG6+/bXCvJ7HZUVNDXi4P9cToClzJVOX5uKsPI5/MUYDEq13scxPyQK63m8SsHg== 93 | dependencies: 94 | "@polkadot/api" "11.2.1" 95 | "@polkadot/api-augment" "11.2.1" 96 | "@polkadot/api-base" "11.2.1" 97 | "@polkadot/rpc-core" "11.2.1" 98 | "@polkadot/types" "11.2.1" 99 | "@polkadot/types-codec" "11.2.1" 100 | "@polkadot/util" "^12.6.2" 101 | "@polkadot/util-crypto" "^12.6.2" 102 | rxjs "^7.8.1" 103 | tslib "^2.6.2" 104 | 105 | "@polkadot/api@^11.2.1", "@polkadot/api@11.2.1": 106 | version "11.2.1" 107 | resolved "https://registry.npmjs.org/@polkadot/api/-/api-11.2.1.tgz" 108 | integrity sha512-NwcWadMt+mrJ3T7RuwpnaIYtH4x0eix+GiKRtLMtIO32uAfhwVyMnqvLtxDxa4XDJ/es2rtSMYG+t0b1BTM+xQ== 109 | dependencies: 110 | "@polkadot/api-augment" "11.2.1" 111 | "@polkadot/api-base" "11.2.1" 112 | "@polkadot/api-derive" "11.2.1" 113 | "@polkadot/keyring" "^12.6.2" 114 | "@polkadot/rpc-augment" "11.2.1" 115 | "@polkadot/rpc-core" "11.2.1" 116 | "@polkadot/rpc-provider" "11.2.1" 117 | "@polkadot/types" "11.2.1" 118 | "@polkadot/types-augment" "11.2.1" 119 | "@polkadot/types-codec" "11.2.1" 120 | "@polkadot/types-create" "11.2.1" 121 | "@polkadot/types-known" "11.2.1" 122 | "@polkadot/util" "^12.6.2" 123 | "@polkadot/util-crypto" "^12.6.2" 124 | eventemitter3 "^5.0.1" 125 | rxjs "^7.8.1" 126 | tslib "^2.6.2" 127 | 128 | "@polkadot/keyring@^12.6.2": 129 | version "12.6.2" 130 | resolved "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.6.2.tgz" 131 | integrity sha512-O3Q7GVmRYm8q7HuB3S0+Yf/q/EB2egKRRU3fv9b3B7V+A52tKzA+vIwEmNVaD1g5FKW9oB97rmpggs0zaKFqHw== 132 | dependencies: 133 | "@polkadot/util" "12.6.2" 134 | "@polkadot/util-crypto" "12.6.2" 135 | tslib "^2.6.2" 136 | 137 | "@polkadot/networks@^12.6.2", "@polkadot/networks@12.6.2": 138 | version "12.6.2" 139 | resolved "https://registry.npmjs.org/@polkadot/networks/-/networks-12.6.2.tgz" 140 | integrity sha512-1oWtZm1IvPWqvMrldVH6NI2gBoCndl5GEwx7lAuQWGr7eNL+6Bdc5K3Z9T0MzFvDGoi2/CBqjX9dRKo39pDC/w== 141 | dependencies: 142 | "@polkadot/util" "12.6.2" 143 | "@substrate/ss58-registry" "^1.44.0" 144 | tslib "^2.6.2" 145 | 146 | "@polkadot/rpc-augment@11.2.1": 147 | version "11.2.1" 148 | resolved "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-11.2.1.tgz" 149 | integrity sha512-AbkqWTnKCi71LdqFVbCyYelf5N/Wtj4jFnpRd8z7tIbbiAnNRW61dBgdF9jZ8jd9Z0JvfAmCmG17uCEdsqfNjA== 150 | dependencies: 151 | "@polkadot/rpc-core" "11.2.1" 152 | "@polkadot/types" "11.2.1" 153 | "@polkadot/types-codec" "11.2.1" 154 | "@polkadot/util" "^12.6.2" 155 | tslib "^2.6.2" 156 | 157 | "@polkadot/rpc-core@11.2.1": 158 | version "11.2.1" 159 | resolved "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-11.2.1.tgz" 160 | integrity sha512-GHNIHDvBts6HDvySfYksuLccaVnI+fc7ubY1uYcJMoyGv9pLhMtveH4Ft7NTxqkBqopbPXZHc8ca9CaIeBVr7w== 161 | dependencies: 162 | "@polkadot/rpc-augment" "11.2.1" 163 | "@polkadot/rpc-provider" "11.2.1" 164 | "@polkadot/types" "11.2.1" 165 | "@polkadot/util" "^12.6.2" 166 | rxjs "^7.8.1" 167 | tslib "^2.6.2" 168 | 169 | "@polkadot/rpc-provider@11.2.1": 170 | version "11.2.1" 171 | resolved "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-11.2.1.tgz" 172 | integrity sha512-TO9pdxNmTweK1vi9JYUAoLr/JYJUwPJTTdrSJrmGmiNPaM7txbQVgtT4suQYflVZTgXUYR7OYQ201fH+Qb9J9w== 173 | dependencies: 174 | "@polkadot/keyring" "^12.6.2" 175 | "@polkadot/types" "11.2.1" 176 | "@polkadot/types-support" "11.2.1" 177 | "@polkadot/util" "^12.6.2" 178 | "@polkadot/util-crypto" "^12.6.2" 179 | "@polkadot/x-fetch" "^12.6.2" 180 | "@polkadot/x-global" "^12.6.2" 181 | "@polkadot/x-ws" "^12.6.2" 182 | eventemitter3 "^5.0.1" 183 | mock-socket "^9.3.1" 184 | nock "^13.5.0" 185 | tslib "^2.6.2" 186 | optionalDependencies: 187 | "@substrate/connect" "0.8.10" 188 | 189 | "@polkadot/types-augment@11.2.1": 190 | version "11.2.1" 191 | resolved "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-11.2.1.tgz" 192 | integrity sha512-3zBsuSKjZlMEeDVqPTkLnFvjPdyGcW3UBihzCgpTmXhLSuwTbsscMwKtKwIPkOHHQPYJYyZXTMkurMXCJOz2kA== 193 | dependencies: 194 | "@polkadot/types" "11.2.1" 195 | "@polkadot/types-codec" "11.2.1" 196 | "@polkadot/util" "^12.6.2" 197 | tslib "^2.6.2" 198 | 199 | "@polkadot/types-codec@11.2.1": 200 | version "11.2.1" 201 | resolved "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-11.2.1.tgz" 202 | integrity sha512-9VRRf1g/nahAC3/VSiCSUIRL7uuup04JEZLIAG2LaDgmCBOSV9dt1Yj9114bRUrHHkeUSBmiq64+YX1hZMpQzQ== 203 | dependencies: 204 | "@polkadot/util" "^12.6.2" 205 | "@polkadot/x-bigint" "^12.6.2" 206 | tslib "^2.6.2" 207 | 208 | "@polkadot/types-create@11.2.1": 209 | version "11.2.1" 210 | resolved "https://registry.npmjs.org/@polkadot/types-create/-/types-create-11.2.1.tgz" 211 | integrity sha512-Y0Zri7x6/rHURVNLMi6i1+rmJDLCn8OQl8BIvRmsIBkCYh2oCzy0g9aqVoCdm+QnoUU5ZNtu+U/gj1kL5ODivQ== 212 | dependencies: 213 | "@polkadot/types-codec" "11.2.1" 214 | "@polkadot/util" "^12.6.2" 215 | tslib "^2.6.2" 216 | 217 | "@polkadot/types-known@11.2.1": 218 | version "11.2.1" 219 | resolved "https://registry.npmjs.org/@polkadot/types-known/-/types-known-11.2.1.tgz" 220 | integrity sha512-dnbmVKagVI6ARuZaGMGc67HPeHGrR7/lcwfS7jGzEmRcoQk7p/UQjWfOk/LG9NzvQkmRVbE0Gqskn4VorqnTbA== 221 | dependencies: 222 | "@polkadot/networks" "^12.6.2" 223 | "@polkadot/types" "11.2.1" 224 | "@polkadot/types-codec" "11.2.1" 225 | "@polkadot/types-create" "11.2.1" 226 | "@polkadot/util" "^12.6.2" 227 | tslib "^2.6.2" 228 | 229 | "@polkadot/types-support@11.2.1": 230 | version "11.2.1" 231 | resolved "https://registry.npmjs.org/@polkadot/types-support/-/types-support-11.2.1.tgz" 232 | integrity sha512-VGSUDUEQjt8K3Bv8gHYAE/nD98qPPuZ2DcikM9z9isw04qj2amxZaS26+iknJ9KSCzWgrNBHjcr5Q0o76//2yA== 233 | dependencies: 234 | "@polkadot/util" "^12.6.2" 235 | tslib "^2.6.2" 236 | 237 | "@polkadot/types@^11.2.1", "@polkadot/types@11.2.1": 238 | version "11.2.1" 239 | resolved "https://registry.npmjs.org/@polkadot/types/-/types-11.2.1.tgz" 240 | integrity sha512-NVPhO/eFPkL8arWk4xVbsJzRdGfue3gJK+A2iYzOfCr9rDHEj99B+E2Z0Or6zDN6n+thgQYwsr19rKgXvAc18Q== 241 | dependencies: 242 | "@polkadot/keyring" "^12.6.2" 243 | "@polkadot/types-augment" "11.2.1" 244 | "@polkadot/types-codec" "11.2.1" 245 | "@polkadot/types-create" "11.2.1" 246 | "@polkadot/util" "^12.6.2" 247 | "@polkadot/util-crypto" "^12.6.2" 248 | rxjs "^7.8.1" 249 | tslib "^2.6.2" 250 | 251 | "@polkadot/util-crypto@^12.6.2", "@polkadot/util-crypto@12.6.2": 252 | version "12.6.2" 253 | resolved "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.6.2.tgz" 254 | integrity sha512-FEWI/dJ7wDMNN1WOzZAjQoIcCP/3vz3wvAp5QQm+lOrzOLj0iDmaIGIcBkz8HVm3ErfSe/uKP0KS4jgV/ib+Mg== 255 | dependencies: 256 | "@noble/curves" "^1.3.0" 257 | "@noble/hashes" "^1.3.3" 258 | "@polkadot/networks" "12.6.2" 259 | "@polkadot/util" "12.6.2" 260 | "@polkadot/wasm-crypto" "^7.3.2" 261 | "@polkadot/wasm-util" "^7.3.2" 262 | "@polkadot/x-bigint" "12.6.2" 263 | "@polkadot/x-randomvalues" "12.6.2" 264 | "@scure/base" "^1.1.5" 265 | tslib "^2.6.2" 266 | 267 | "@polkadot/util@*", "@polkadot/util@^12.6.2", "@polkadot/util@12.6.2": 268 | version "12.6.2" 269 | resolved "https://registry.npmjs.org/@polkadot/util/-/util-12.6.2.tgz" 270 | integrity sha512-l8TubR7CLEY47240uki0TQzFvtnxFIO7uI/0GoWzpYD/O62EIAMRsuY01N4DuwgKq2ZWD59WhzsLYmA5K6ksdw== 271 | dependencies: 272 | "@polkadot/x-bigint" "12.6.2" 273 | "@polkadot/x-global" "12.6.2" 274 | "@polkadot/x-textdecoder" "12.6.2" 275 | "@polkadot/x-textencoder" "12.6.2" 276 | "@types/bn.js" "^5.1.5" 277 | bn.js "^5.2.1" 278 | tslib "^2.6.2" 279 | 280 | "@polkadot/wasm-bridge@7.3.2": 281 | version "7.3.2" 282 | resolved "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.3.2.tgz" 283 | integrity sha512-AJEXChcf/nKXd5Q/YLEV5dXQMle3UNT7jcXYmIffZAo/KI394a+/24PaISyQjoNC0fkzS1Q8T5pnGGHmXiVz2g== 284 | dependencies: 285 | "@polkadot/wasm-util" "7.3.2" 286 | tslib "^2.6.2" 287 | 288 | "@polkadot/wasm-crypto-asmjs@7.3.2": 289 | version "7.3.2" 290 | resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.3.2.tgz" 291 | integrity sha512-QP5eiUqUFur/2UoF2KKKYJcesc71fXhQFLT3D4ZjG28Mfk2ZPI0QNRUfpcxVQmIUpV5USHg4geCBNuCYsMm20Q== 292 | dependencies: 293 | tslib "^2.6.2" 294 | 295 | "@polkadot/wasm-crypto-init@7.3.2": 296 | version "7.3.2" 297 | resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.3.2.tgz" 298 | integrity sha512-FPq73zGmvZtnuJaFV44brze3Lkrki3b4PebxCy9Fplw8nTmisKo9Xxtfew08r0njyYh+uiJRAxPCXadkC9sc8g== 299 | dependencies: 300 | "@polkadot/wasm-bridge" "7.3.2" 301 | "@polkadot/wasm-crypto-asmjs" "7.3.2" 302 | "@polkadot/wasm-crypto-wasm" "7.3.2" 303 | "@polkadot/wasm-util" "7.3.2" 304 | tslib "^2.6.2" 305 | 306 | "@polkadot/wasm-crypto-wasm@7.3.2": 307 | version "7.3.2" 308 | resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.3.2.tgz" 309 | integrity sha512-15wd0EMv9IXs5Abp1ZKpKKAVyZPhATIAHfKsyoWCEFDLSOA0/K0QGOxzrAlsrdUkiKZOq7uzSIgIDgW8okx2Mw== 310 | dependencies: 311 | "@polkadot/wasm-util" "7.3.2" 312 | tslib "^2.6.2" 313 | 314 | "@polkadot/wasm-crypto@^7.3.2": 315 | version "7.3.2" 316 | resolved "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.3.2.tgz" 317 | integrity sha512-+neIDLSJ6jjVXsjyZ5oLSv16oIpwp+PxFqTUaZdZDoA2EyFRQB8pP7+qLsMNk+WJuhuJ4qXil/7XiOnZYZ+wxw== 318 | dependencies: 319 | "@polkadot/wasm-bridge" "7.3.2" 320 | "@polkadot/wasm-crypto-asmjs" "7.3.2" 321 | "@polkadot/wasm-crypto-init" "7.3.2" 322 | "@polkadot/wasm-crypto-wasm" "7.3.2" 323 | "@polkadot/wasm-util" "7.3.2" 324 | tslib "^2.6.2" 325 | 326 | "@polkadot/wasm-util@*", "@polkadot/wasm-util@^7.3.2", "@polkadot/wasm-util@7.3.2": 327 | version "7.3.2" 328 | resolved "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.3.2.tgz" 329 | integrity sha512-bmD+Dxo1lTZyZNxbyPE380wd82QsX+43mgCm40boyKrRppXEyQmWT98v/Poc7chLuskYb6X8IQ6lvvK2bGR4Tg== 330 | dependencies: 331 | tslib "^2.6.2" 332 | 333 | "@polkadot/x-bigint@^12.6.2", "@polkadot/x-bigint@12.6.2": 334 | version "12.6.2" 335 | resolved "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.6.2.tgz" 336 | integrity sha512-HSIk60uFPX4GOFZSnIF7VYJz7WZA7tpFJsne7SzxOooRwMTWEtw3fUpFy5cYYOeLh17/kHH1Y7SVcuxzVLc74Q== 337 | dependencies: 338 | "@polkadot/x-global" "12.6.2" 339 | tslib "^2.6.2" 340 | 341 | "@polkadot/x-fetch@^12.6.2": 342 | version "12.6.2" 343 | resolved "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.6.2.tgz" 344 | integrity sha512-8wM/Z9JJPWN1pzSpU7XxTI1ldj/AfC8hKioBlUahZ8gUiJaOF7K9XEFCrCDLis/A1BoOu7Ne6WMx/vsJJIbDWw== 345 | dependencies: 346 | "@polkadot/x-global" "12.6.2" 347 | node-fetch "^3.3.2" 348 | tslib "^2.6.2" 349 | 350 | "@polkadot/x-global@^12.6.2", "@polkadot/x-global@12.6.2": 351 | version "12.6.2" 352 | resolved "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.6.2.tgz" 353 | integrity sha512-a8d6m+PW98jmsYDtAWp88qS4dl8DyqUBsd0S+WgyfSMtpEXu6v9nXDgPZgwF5xdDvXhm+P0ZfVkVTnIGrScb5g== 354 | dependencies: 355 | tslib "^2.6.2" 356 | 357 | "@polkadot/x-randomvalues@*", "@polkadot/x-randomvalues@12.6.2": 358 | version "12.6.2" 359 | resolved "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.6.2.tgz" 360 | integrity sha512-Vr8uG7rH2IcNJwtyf5ebdODMcr0XjoCpUbI91Zv6AlKVYOGKZlKLYJHIwpTaKKB+7KPWyQrk4Mlym/rS7v9feg== 361 | dependencies: 362 | "@polkadot/x-global" "12.6.2" 363 | tslib "^2.6.2" 364 | 365 | "@polkadot/x-textdecoder@12.6.2": 366 | version "12.6.2" 367 | resolved "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.6.2.tgz" 368 | integrity sha512-M1Bir7tYvNappfpFWXOJcnxUhBUFWkUFIdJSyH0zs5LmFtFdbKAeiDXxSp2Swp5ddOZdZgPac294/o2TnQKN1w== 369 | dependencies: 370 | "@polkadot/x-global" "12.6.2" 371 | tslib "^2.6.2" 372 | 373 | "@polkadot/x-textencoder@12.6.2": 374 | version "12.6.2" 375 | resolved "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.6.2.tgz" 376 | integrity sha512-4N+3UVCpI489tUJ6cv3uf0PjOHvgGp9Dl+SZRLgFGt9mvxnvpW/7+XBADRMtlG4xi5gaRK7bgl5bmY6OMDsNdw== 377 | dependencies: 378 | "@polkadot/x-global" "12.6.2" 379 | tslib "^2.6.2" 380 | 381 | "@polkadot/x-ws@^12.6.2": 382 | version "12.6.2" 383 | resolved "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.6.2.tgz" 384 | integrity sha512-cGZWo7K5eRRQCRl2LrcyCYsrc3lRbTlixZh3AzgU8uX4wASVGRlNWi/Hf4TtHNe1ExCDmxabJzdIsABIfrr7xw== 385 | dependencies: 386 | "@polkadot/x-global" "12.6.2" 387 | tslib "^2.6.2" 388 | ws "^8.15.1" 389 | 390 | "@scure/base@^1.1.1", "@scure/base@^1.1.5": 391 | version "1.1.6" 392 | resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz" 393 | integrity sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g== 394 | 395 | "@slack/logger@^4.0.0": 396 | version "4.0.0" 397 | resolved "https://registry.npmjs.org/@slack/logger/-/logger-4.0.0.tgz" 398 | integrity sha512-Wz7QYfPAlG/DR+DfABddUZeNgoeY7d1J39OCR2jR+v7VBsB8ezulDK5szTnDDPDwLH5IWhLvXIHlCFZV7MSKgA== 399 | dependencies: 400 | "@types/node" ">=18.0.0" 401 | 402 | "@slack/types@^2.9.0": 403 | version "2.11.0" 404 | resolved "https://registry.npmjs.org/@slack/types/-/types-2.11.0.tgz" 405 | integrity sha512-UlIrDWvuLaDly3QZhCPnwUSI/KYmV1N9LyhuH6EDKCRS1HWZhyTG3Ja46T3D0rYfqdltKYFXbJSSRPwZpwO0cQ== 406 | 407 | "@slack/web-api@^7.0.4": 408 | version "7.0.4" 409 | resolved "https://registry.npmjs.org/@slack/web-api/-/web-api-7.0.4.tgz" 410 | integrity sha512-21tbte7N8itwjG7nsiQbDmXP9T/oqEILuvyL2UtgaZxfSY4a1JWWsLGL5n/hcgS2WE2oxmEHsBuhuRkZDwDovw== 411 | dependencies: 412 | "@slack/logger" "^4.0.0" 413 | "@slack/types" "^2.9.0" 414 | "@types/node" ">=18.0.0" 415 | "@types/retry" "0.12.0" 416 | axios "^1.6.5" 417 | eventemitter3 "^5.0.1" 418 | form-data "^4.0.0" 419 | is-electron "2.2.2" 420 | is-stream "^2" 421 | p-queue "^6" 422 | p-retry "^4" 423 | retry "^0.13.1" 424 | 425 | "@substrate/connect-extension-protocol@^2.0.0": 426 | version "2.0.0" 427 | resolved "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.0.0.tgz" 428 | integrity sha512-nKu8pDrE3LNCEgJjZe1iGXzaD6OSIDD4Xzz/yo4KO9mQ6LBvf49BVrt4qxBFGL6++NneLiWUZGoh+VSd4PyVIg== 429 | 430 | "@substrate/connect-known-chains@^1.1.4": 431 | version "1.1.5" 432 | resolved "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.1.5.tgz" 433 | integrity sha512-GCdDMs5q9xDYyP/KEwrlWMdqv8OIPjuVMZvNowvUrvEFo5d+x+VqfRPzyl/RbV+snRQVWTTacRydE7GqyjCYPQ== 434 | 435 | "@substrate/connect@0.8.10": 436 | version "0.8.10" 437 | resolved "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.10.tgz" 438 | integrity sha512-DIyQ13DDlXqVFnLV+S6/JDgiGowVRRrh18kahieJxhgvzcWicw5eLc6jpfQ0moVVLBYkO7rctB5Wreldwpva8w== 439 | dependencies: 440 | "@substrate/connect-extension-protocol" "^2.0.0" 441 | "@substrate/connect-known-chains" "^1.1.4" 442 | "@substrate/light-client-extension-helpers" "^0.0.6" 443 | smoldot "2.0.22" 444 | 445 | "@substrate/light-client-extension-helpers@^0.0.6": 446 | version "0.0.6" 447 | resolved "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-0.0.6.tgz" 448 | integrity sha512-girltEuxQ1BvkJWmc8JJlk4ZxnlGXc/wkLcNguhY+UoDEMBK0LsdtfzQKIfrIehi4QdeSBlFEFBoI4RqPmsZzA== 449 | dependencies: 450 | "@polkadot-api/json-rpc-provider" "0.0.1" 451 | "@polkadot-api/json-rpc-provider-proxy" "0.0.1" 452 | "@polkadot-api/observable-client" "0.1.0" 453 | "@polkadot-api/substrate-client" "0.0.1" 454 | "@substrate/connect-extension-protocol" "^2.0.0" 455 | "@substrate/connect-known-chains" "^1.1.4" 456 | rxjs "^7.8.1" 457 | 458 | "@substrate/ss58-registry@^1.44.0": 459 | version "1.48.0" 460 | resolved "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.48.0.tgz" 461 | integrity sha512-lE9TGgtd93fTEIoHhSdtvSFBoCsvTbqiCvQIMvX4m6BO/hESywzzTzTFMVP1doBwDDMAN4lsMfIM3X3pdmt7kQ== 462 | 463 | "@types/bn.js@^5.1.5": 464 | version "5.1.5" 465 | resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz" 466 | integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== 467 | dependencies: 468 | "@types/node" "*" 469 | 470 | "@types/node@*", "@types/node@>=18.0.0": 471 | version "20.14.2" 472 | resolved "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz" 473 | integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q== 474 | dependencies: 475 | undici-types "~5.26.4" 476 | 477 | "@types/retry@0.12.0": 478 | version "0.12.0" 479 | resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz" 480 | integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== 481 | 482 | asynckit@^0.4.0: 483 | version "0.4.0" 484 | resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" 485 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 486 | 487 | axios@^1.6.5: 488 | version "1.6.8" 489 | resolved "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz" 490 | integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== 491 | dependencies: 492 | follow-redirects "^1.15.6" 493 | form-data "^4.0.0" 494 | proxy-from-env "^1.1.0" 495 | 496 | bn.js@^5.2.1: 497 | version "5.2.1" 498 | resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" 499 | integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== 500 | 501 | combined-stream@^1.0.8: 502 | version "1.0.8" 503 | resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" 504 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 505 | dependencies: 506 | delayed-stream "~1.0.0" 507 | 508 | data-uri-to-buffer@^4.0.0: 509 | version "4.0.1" 510 | resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz" 511 | integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== 512 | 513 | debug@^4.1.0: 514 | version "4.3.5" 515 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz" 516 | integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== 517 | dependencies: 518 | ms "2.1.2" 519 | 520 | delayed-stream@~1.0.0: 521 | version "1.0.0" 522 | resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" 523 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 524 | 525 | eventemitter3@^4.0.4: 526 | version "4.0.7" 527 | resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" 528 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== 529 | 530 | eventemitter3@^5.0.1: 531 | version "5.0.1" 532 | resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" 533 | integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== 534 | 535 | fetch-blob@^3.1.2, fetch-blob@^3.1.4: 536 | version "3.2.0" 537 | resolved "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz" 538 | integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== 539 | dependencies: 540 | node-domexception "^1.0.0" 541 | web-streams-polyfill "^3.0.3" 542 | 543 | follow-redirects@^1.15.6: 544 | version "1.15.6" 545 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz" 546 | integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== 547 | 548 | form-data@^4.0.0: 549 | version "4.0.0" 550 | resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" 551 | integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== 552 | dependencies: 553 | asynckit "^0.4.0" 554 | combined-stream "^1.0.8" 555 | mime-types "^2.1.12" 556 | 557 | formdata-polyfill@^4.0.10: 558 | version "4.0.10" 559 | resolved "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz" 560 | integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== 561 | dependencies: 562 | fetch-blob "^3.1.2" 563 | 564 | is-electron@2.2.2: 565 | version "2.2.2" 566 | resolved "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz" 567 | integrity sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg== 568 | 569 | is-stream@^2: 570 | version "2.0.1" 571 | resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" 572 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 573 | 574 | json-stringify-safe@^5.0.1: 575 | version "5.0.1" 576 | resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" 577 | integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== 578 | 579 | mime-db@1.52.0: 580 | version "1.52.0" 581 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" 582 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 583 | 584 | mime-types@^2.1.12: 585 | version "2.1.35" 586 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" 587 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 588 | dependencies: 589 | mime-db "1.52.0" 590 | 591 | mock-socket@^9.3.1: 592 | version "9.3.1" 593 | resolved "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz" 594 | integrity sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw== 595 | 596 | ms@2.1.2: 597 | version "2.1.2" 598 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" 599 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 600 | 601 | nock@^13.5.0: 602 | version "13.5.4" 603 | resolved "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz" 604 | integrity sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw== 605 | dependencies: 606 | debug "^4.1.0" 607 | json-stringify-safe "^5.0.1" 608 | propagate "^2.0.0" 609 | 610 | node-domexception@^1.0.0: 611 | version "1.0.0" 612 | resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz" 613 | integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== 614 | 615 | node-fetch@^3.3.2: 616 | version "3.3.2" 617 | resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz" 618 | integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== 619 | dependencies: 620 | data-uri-to-buffer "^4.0.0" 621 | fetch-blob "^3.1.4" 622 | formdata-polyfill "^4.0.10" 623 | 624 | p-finally@^1.0.0: 625 | version "1.0.0" 626 | resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" 627 | integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== 628 | 629 | p-queue@^6: 630 | version "6.6.2" 631 | resolved "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz" 632 | integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== 633 | dependencies: 634 | eventemitter3 "^4.0.4" 635 | p-timeout "^3.2.0" 636 | 637 | p-retry@^4: 638 | version "4.6.2" 639 | resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz" 640 | integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== 641 | dependencies: 642 | "@types/retry" "0.12.0" 643 | retry "^0.13.1" 644 | 645 | p-timeout@^3.2.0: 646 | version "3.2.0" 647 | resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz" 648 | integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== 649 | dependencies: 650 | p-finally "^1.0.0" 651 | 652 | propagate@^2.0.0: 653 | version "2.0.1" 654 | resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz" 655 | integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== 656 | 657 | proxy-from-env@^1.1.0: 658 | version "1.1.0" 659 | resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" 660 | integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== 661 | 662 | retry@^0.13.1: 663 | version "0.13.1" 664 | resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" 665 | integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== 666 | 667 | rxjs@^7.8.1, rxjs@>=7.8.0: 668 | version "7.8.1" 669 | resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" 670 | integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== 671 | dependencies: 672 | tslib "^2.1.0" 673 | 674 | scale-ts@^1.6.0: 675 | version "1.6.0" 676 | resolved "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.0.tgz" 677 | integrity sha512-Ja5VCjNZR8TGKhUumy9clVVxcDpM+YFjAnkMuwQy68Hixio3VRRvWdE3g8T/yC+HXA0ZDQl2TGyUmtmbcVl40Q== 678 | 679 | smoldot@2.0.22, smoldot@2.x: 680 | version "2.0.22" 681 | resolved "https://registry.npmjs.org/smoldot/-/smoldot-2.0.22.tgz" 682 | integrity sha512-B50vRgTY6v3baYH6uCgL15tfaag5tcS2o/P5q1OiXcKGv1axZDfz2dzzMuIkVpyMR2ug11F6EAtQlmYBQd292g== 683 | dependencies: 684 | ws "^8.8.1" 685 | 686 | tslib@^2.1.0, tslib@^2.6.2: 687 | version "2.6.3" 688 | resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz" 689 | integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== 690 | 691 | typescript@^5.4.5: 692 | version "5.4.5" 693 | resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz" 694 | integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== 695 | 696 | undici-types@~5.26.4: 697 | version "5.26.5" 698 | resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" 699 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== 700 | 701 | web-streams-polyfill@^3.0.3: 702 | version "3.3.3" 703 | resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz" 704 | integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== 705 | 706 | ws@^8.15.1, ws@^8.8.1: 707 | version "8.17.0" 708 | resolved "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz" 709 | integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow== 710 | -------------------------------------------------------------------------------- /polkadot-payout-cron/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "polkadot-payout-cron", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "@polkadot/api": "^11.2.1", 9 | "@polkadot/types": "^11.2.1", 10 | "@slack/web-api": "^7.0.4", 11 | "typescript": "^5.4.5" 12 | } 13 | }, 14 | "node_modules/@noble/curves": { 15 | "version": "1.4.0", 16 | "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", 17 | "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", 18 | "dependencies": { 19 | "@noble/hashes": "1.4.0" 20 | }, 21 | "funding": { 22 | "url": "https://paulmillr.com/funding/" 23 | } 24 | }, 25 | "node_modules/@noble/hashes": { 26 | "version": "1.4.0", 27 | "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", 28 | "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", 29 | "engines": { 30 | "node": ">= 16" 31 | }, 32 | "funding": { 33 | "url": "https://paulmillr.com/funding/" 34 | } 35 | }, 36 | "node_modules/@polkadot-api/json-rpc-provider": { 37 | "version": "0.0.1", 38 | "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1.tgz", 39 | "integrity": "sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==", 40 | "optional": true 41 | }, 42 | "node_modules/@polkadot-api/json-rpc-provider-proxy": { 43 | "version": "0.0.1", 44 | "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.0.1.tgz", 45 | "integrity": "sha512-gmVDUP8LpCH0BXewbzqXF2sdHddq1H1q+XrAW2of+KZj4woQkIGBRGTJHeBEVHe30EB+UejR1N2dT4PO/RvDdg==", 46 | "optional": true 47 | }, 48 | "node_modules/@polkadot-api/metadata-builders": { 49 | "version": "0.0.1", 50 | "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.0.1.tgz", 51 | "integrity": "sha512-GCI78BHDzXAF/L2pZD6Aod/yl82adqQ7ftNmKg51ixRL02JpWUA+SpUKTJE5MY1p8kiJJIo09P2um24SiJHxNA==", 52 | "optional": true, 53 | "dependencies": { 54 | "@polkadot-api/substrate-bindings": "0.0.1", 55 | "@polkadot-api/utils": "0.0.1" 56 | } 57 | }, 58 | "node_modules/@polkadot-api/observable-client": { 59 | "version": "0.1.0", 60 | "resolved": "https://registry.npmjs.org/@polkadot-api/observable-client/-/observable-client-0.1.0.tgz", 61 | "integrity": "sha512-GBCGDRztKorTLna/unjl/9SWZcRmvV58o9jwU2Y038VuPXZcr01jcw/1O3x+yeAuwyGzbucI/mLTDa1QoEml3A==", 62 | "optional": true, 63 | "dependencies": { 64 | "@polkadot-api/metadata-builders": "0.0.1", 65 | "@polkadot-api/substrate-bindings": "0.0.1", 66 | "@polkadot-api/substrate-client": "0.0.1", 67 | "@polkadot-api/utils": "0.0.1" 68 | }, 69 | "peerDependencies": { 70 | "rxjs": ">=7.8.0" 71 | } 72 | }, 73 | "node_modules/@polkadot-api/substrate-bindings": { 74 | "version": "0.0.1", 75 | "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.0.1.tgz", 76 | "integrity": "sha512-bAe7a5bOPnuFVmpv7y4BBMRpNTnMmE0jtTqRUw/+D8ZlEHNVEJQGr4wu3QQCl7k1GnSV1wfv3mzIbYjErEBocg==", 77 | "optional": true, 78 | "dependencies": { 79 | "@noble/hashes": "^1.3.1", 80 | "@polkadot-api/utils": "0.0.1", 81 | "@scure/base": "^1.1.1", 82 | "scale-ts": "^1.6.0" 83 | } 84 | }, 85 | "node_modules/@polkadot-api/substrate-client": { 86 | "version": "0.0.1", 87 | "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.0.1.tgz", 88 | "integrity": "sha512-9Bg9SGc3AwE+wXONQoW8GC00N3v6lCZLW74HQzqB6ROdcm5VAHM4CB/xRzWSUF9CXL78ugiwtHx3wBcpx4H4Wg==", 89 | "optional": true 90 | }, 91 | "node_modules/@polkadot-api/utils": { 92 | "version": "0.0.1", 93 | "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.0.1.tgz", 94 | "integrity": "sha512-3j+pRmlF9SgiYDabSdZsBSsN5XHbpXOAce1lWj56IEEaFZVjsiCaxDOA7C9nCcgfVXuvnbxqqEGQvnY+QfBAUw==", 95 | "optional": true 96 | }, 97 | "node_modules/@polkadot/api": { 98 | "version": "11.2.1", 99 | "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-11.2.1.tgz", 100 | "integrity": "sha512-NwcWadMt+mrJ3T7RuwpnaIYtH4x0eix+GiKRtLMtIO32uAfhwVyMnqvLtxDxa4XDJ/es2rtSMYG+t0b1BTM+xQ==", 101 | "dependencies": { 102 | "@polkadot/api-augment": "11.2.1", 103 | "@polkadot/api-base": "11.2.1", 104 | "@polkadot/api-derive": "11.2.1", 105 | "@polkadot/keyring": "^12.6.2", 106 | "@polkadot/rpc-augment": "11.2.1", 107 | "@polkadot/rpc-core": "11.2.1", 108 | "@polkadot/rpc-provider": "11.2.1", 109 | "@polkadot/types": "11.2.1", 110 | "@polkadot/types-augment": "11.2.1", 111 | "@polkadot/types-codec": "11.2.1", 112 | "@polkadot/types-create": "11.2.1", 113 | "@polkadot/types-known": "11.2.1", 114 | "@polkadot/util": "^12.6.2", 115 | "@polkadot/util-crypto": "^12.6.2", 116 | "eventemitter3": "^5.0.1", 117 | "rxjs": "^7.8.1", 118 | "tslib": "^2.6.2" 119 | }, 120 | "engines": { 121 | "node": ">=18" 122 | } 123 | }, 124 | "node_modules/@polkadot/api-augment": { 125 | "version": "11.2.1", 126 | "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-11.2.1.tgz", 127 | "integrity": "sha512-Huo457lCqeavbrf1O/2qQYGNFWURLXndW4vNkj8AP+I757WIqebhc6K3+mz+KoV1aTsX/qwaiEgeoTjrrIwcqA==", 128 | "dependencies": { 129 | "@polkadot/api-base": "11.2.1", 130 | "@polkadot/rpc-augment": "11.2.1", 131 | "@polkadot/types": "11.2.1", 132 | "@polkadot/types-augment": "11.2.1", 133 | "@polkadot/types-codec": "11.2.1", 134 | "@polkadot/util": "^12.6.2", 135 | "tslib": "^2.6.2" 136 | }, 137 | "engines": { 138 | "node": ">=18" 139 | } 140 | }, 141 | "node_modules/@polkadot/api-base": { 142 | "version": "11.2.1", 143 | "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-11.2.1.tgz", 144 | "integrity": "sha512-lVYTHQf8S4rpOJ9d1jvQjviHLE6zljl13vmgs+gXHGJwMAqhhNwKY3ZMQW/u/bRE2uKk0cAlahtsRtiFpjHAfw==", 145 | "dependencies": { 146 | "@polkadot/rpc-core": "11.2.1", 147 | "@polkadot/types": "11.2.1", 148 | "@polkadot/util": "^12.6.2", 149 | "rxjs": "^7.8.1", 150 | "tslib": "^2.6.2" 151 | }, 152 | "engines": { 153 | "node": ">=18" 154 | } 155 | }, 156 | "node_modules/@polkadot/api-derive": { 157 | "version": "11.2.1", 158 | "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-11.2.1.tgz", 159 | "integrity": "sha512-ts6D6tXmvhBpHDT7E03TStXfG6+/bXCvJ7HZUVNDXi4P9cToClzJVOX5uKsPI5/MUYDEq13scxPyQK63m8SsHg==", 160 | "dependencies": { 161 | "@polkadot/api": "11.2.1", 162 | "@polkadot/api-augment": "11.2.1", 163 | "@polkadot/api-base": "11.2.1", 164 | "@polkadot/rpc-core": "11.2.1", 165 | "@polkadot/types": "11.2.1", 166 | "@polkadot/types-codec": "11.2.1", 167 | "@polkadot/util": "^12.6.2", 168 | "@polkadot/util-crypto": "^12.6.2", 169 | "rxjs": "^7.8.1", 170 | "tslib": "^2.6.2" 171 | }, 172 | "engines": { 173 | "node": ">=18" 174 | } 175 | }, 176 | "node_modules/@polkadot/keyring": { 177 | "version": "12.6.2", 178 | "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.6.2.tgz", 179 | "integrity": "sha512-O3Q7GVmRYm8q7HuB3S0+Yf/q/EB2egKRRU3fv9b3B7V+A52tKzA+vIwEmNVaD1g5FKW9oB97rmpggs0zaKFqHw==", 180 | "dependencies": { 181 | "@polkadot/util": "12.6.2", 182 | "@polkadot/util-crypto": "12.6.2", 183 | "tslib": "^2.6.2" 184 | }, 185 | "engines": { 186 | "node": ">=18" 187 | }, 188 | "peerDependencies": { 189 | "@polkadot/util": "12.6.2", 190 | "@polkadot/util-crypto": "12.6.2" 191 | } 192 | }, 193 | "node_modules/@polkadot/networks": { 194 | "version": "12.6.2", 195 | "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-12.6.2.tgz", 196 | "integrity": "sha512-1oWtZm1IvPWqvMrldVH6NI2gBoCndl5GEwx7lAuQWGr7eNL+6Bdc5K3Z9T0MzFvDGoi2/CBqjX9dRKo39pDC/w==", 197 | "dependencies": { 198 | "@polkadot/util": "12.6.2", 199 | "@substrate/ss58-registry": "^1.44.0", 200 | "tslib": "^2.6.2" 201 | }, 202 | "engines": { 203 | "node": ">=18" 204 | } 205 | }, 206 | "node_modules/@polkadot/rpc-augment": { 207 | "version": "11.2.1", 208 | "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-11.2.1.tgz", 209 | "integrity": "sha512-AbkqWTnKCi71LdqFVbCyYelf5N/Wtj4jFnpRd8z7tIbbiAnNRW61dBgdF9jZ8jd9Z0JvfAmCmG17uCEdsqfNjA==", 210 | "dependencies": { 211 | "@polkadot/rpc-core": "11.2.1", 212 | "@polkadot/types": "11.2.1", 213 | "@polkadot/types-codec": "11.2.1", 214 | "@polkadot/util": "^12.6.2", 215 | "tslib": "^2.6.2" 216 | }, 217 | "engines": { 218 | "node": ">=18" 219 | } 220 | }, 221 | "node_modules/@polkadot/rpc-core": { 222 | "version": "11.2.1", 223 | "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-11.2.1.tgz", 224 | "integrity": "sha512-GHNIHDvBts6HDvySfYksuLccaVnI+fc7ubY1uYcJMoyGv9pLhMtveH4Ft7NTxqkBqopbPXZHc8ca9CaIeBVr7w==", 225 | "dependencies": { 226 | "@polkadot/rpc-augment": "11.2.1", 227 | "@polkadot/rpc-provider": "11.2.1", 228 | "@polkadot/types": "11.2.1", 229 | "@polkadot/util": "^12.6.2", 230 | "rxjs": "^7.8.1", 231 | "tslib": "^2.6.2" 232 | }, 233 | "engines": { 234 | "node": ">=18" 235 | } 236 | }, 237 | "node_modules/@polkadot/rpc-provider": { 238 | "version": "11.2.1", 239 | "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-11.2.1.tgz", 240 | "integrity": "sha512-TO9pdxNmTweK1vi9JYUAoLr/JYJUwPJTTdrSJrmGmiNPaM7txbQVgtT4suQYflVZTgXUYR7OYQ201fH+Qb9J9w==", 241 | "dependencies": { 242 | "@polkadot/keyring": "^12.6.2", 243 | "@polkadot/types": "11.2.1", 244 | "@polkadot/types-support": "11.2.1", 245 | "@polkadot/util": "^12.6.2", 246 | "@polkadot/util-crypto": "^12.6.2", 247 | "@polkadot/x-fetch": "^12.6.2", 248 | "@polkadot/x-global": "^12.6.2", 249 | "@polkadot/x-ws": "^12.6.2", 250 | "eventemitter3": "^5.0.1", 251 | "mock-socket": "^9.3.1", 252 | "nock": "^13.5.0", 253 | "tslib": "^2.6.2" 254 | }, 255 | "engines": { 256 | "node": ">=18" 257 | }, 258 | "optionalDependencies": { 259 | "@substrate/connect": "0.8.10" 260 | } 261 | }, 262 | "node_modules/@polkadot/types": { 263 | "version": "11.2.1", 264 | "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-11.2.1.tgz", 265 | "integrity": "sha512-NVPhO/eFPkL8arWk4xVbsJzRdGfue3gJK+A2iYzOfCr9rDHEj99B+E2Z0Or6zDN6n+thgQYwsr19rKgXvAc18Q==", 266 | "dependencies": { 267 | "@polkadot/keyring": "^12.6.2", 268 | "@polkadot/types-augment": "11.2.1", 269 | "@polkadot/types-codec": "11.2.1", 270 | "@polkadot/types-create": "11.2.1", 271 | "@polkadot/util": "^12.6.2", 272 | "@polkadot/util-crypto": "^12.6.2", 273 | "rxjs": "^7.8.1", 274 | "tslib": "^2.6.2" 275 | }, 276 | "engines": { 277 | "node": ">=18" 278 | } 279 | }, 280 | "node_modules/@polkadot/types-augment": { 281 | "version": "11.2.1", 282 | "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-11.2.1.tgz", 283 | "integrity": "sha512-3zBsuSKjZlMEeDVqPTkLnFvjPdyGcW3UBihzCgpTmXhLSuwTbsscMwKtKwIPkOHHQPYJYyZXTMkurMXCJOz2kA==", 284 | "dependencies": { 285 | "@polkadot/types": "11.2.1", 286 | "@polkadot/types-codec": "11.2.1", 287 | "@polkadot/util": "^12.6.2", 288 | "tslib": "^2.6.2" 289 | }, 290 | "engines": { 291 | "node": ">=18" 292 | } 293 | }, 294 | "node_modules/@polkadot/types-codec": { 295 | "version": "11.2.1", 296 | "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-11.2.1.tgz", 297 | "integrity": "sha512-9VRRf1g/nahAC3/VSiCSUIRL7uuup04JEZLIAG2LaDgmCBOSV9dt1Yj9114bRUrHHkeUSBmiq64+YX1hZMpQzQ==", 298 | "dependencies": { 299 | "@polkadot/util": "^12.6.2", 300 | "@polkadot/x-bigint": "^12.6.2", 301 | "tslib": "^2.6.2" 302 | }, 303 | "engines": { 304 | "node": ">=18" 305 | } 306 | }, 307 | "node_modules/@polkadot/types-create": { 308 | "version": "11.2.1", 309 | "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-11.2.1.tgz", 310 | "integrity": "sha512-Y0Zri7x6/rHURVNLMi6i1+rmJDLCn8OQl8BIvRmsIBkCYh2oCzy0g9aqVoCdm+QnoUU5ZNtu+U/gj1kL5ODivQ==", 311 | "dependencies": { 312 | "@polkadot/types-codec": "11.2.1", 313 | "@polkadot/util": "^12.6.2", 314 | "tslib": "^2.6.2" 315 | }, 316 | "engines": { 317 | "node": ">=18" 318 | } 319 | }, 320 | "node_modules/@polkadot/types-known": { 321 | "version": "11.2.1", 322 | "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-11.2.1.tgz", 323 | "integrity": "sha512-dnbmVKagVI6ARuZaGMGc67HPeHGrR7/lcwfS7jGzEmRcoQk7p/UQjWfOk/LG9NzvQkmRVbE0Gqskn4VorqnTbA==", 324 | "dependencies": { 325 | "@polkadot/networks": "^12.6.2", 326 | "@polkadot/types": "11.2.1", 327 | "@polkadot/types-codec": "11.2.1", 328 | "@polkadot/types-create": "11.2.1", 329 | "@polkadot/util": "^12.6.2", 330 | "tslib": "^2.6.2" 331 | }, 332 | "engines": { 333 | "node": ">=18" 334 | } 335 | }, 336 | "node_modules/@polkadot/types-support": { 337 | "version": "11.2.1", 338 | "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-11.2.1.tgz", 339 | "integrity": "sha512-VGSUDUEQjt8K3Bv8gHYAE/nD98qPPuZ2DcikM9z9isw04qj2amxZaS26+iknJ9KSCzWgrNBHjcr5Q0o76//2yA==", 340 | "dependencies": { 341 | "@polkadot/util": "^12.6.2", 342 | "tslib": "^2.6.2" 343 | }, 344 | "engines": { 345 | "node": ">=18" 346 | } 347 | }, 348 | "node_modules/@polkadot/util": { 349 | "version": "12.6.2", 350 | "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-12.6.2.tgz", 351 | "integrity": "sha512-l8TubR7CLEY47240uki0TQzFvtnxFIO7uI/0GoWzpYD/O62EIAMRsuY01N4DuwgKq2ZWD59WhzsLYmA5K6ksdw==", 352 | "dependencies": { 353 | "@polkadot/x-bigint": "12.6.2", 354 | "@polkadot/x-global": "12.6.2", 355 | "@polkadot/x-textdecoder": "12.6.2", 356 | "@polkadot/x-textencoder": "12.6.2", 357 | "@types/bn.js": "^5.1.5", 358 | "bn.js": "^5.2.1", 359 | "tslib": "^2.6.2" 360 | }, 361 | "engines": { 362 | "node": ">=18" 363 | } 364 | }, 365 | "node_modules/@polkadot/util-crypto": { 366 | "version": "12.6.2", 367 | "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.6.2.tgz", 368 | "integrity": "sha512-FEWI/dJ7wDMNN1WOzZAjQoIcCP/3vz3wvAp5QQm+lOrzOLj0iDmaIGIcBkz8HVm3ErfSe/uKP0KS4jgV/ib+Mg==", 369 | "dependencies": { 370 | "@noble/curves": "^1.3.0", 371 | "@noble/hashes": "^1.3.3", 372 | "@polkadot/networks": "12.6.2", 373 | "@polkadot/util": "12.6.2", 374 | "@polkadot/wasm-crypto": "^7.3.2", 375 | "@polkadot/wasm-util": "^7.3.2", 376 | "@polkadot/x-bigint": "12.6.2", 377 | "@polkadot/x-randomvalues": "12.6.2", 378 | "@scure/base": "^1.1.5", 379 | "tslib": "^2.6.2" 380 | }, 381 | "engines": { 382 | "node": ">=18" 383 | }, 384 | "peerDependencies": { 385 | "@polkadot/util": "12.6.2" 386 | } 387 | }, 388 | "node_modules/@polkadot/wasm-bridge": { 389 | "version": "7.3.2", 390 | "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.3.2.tgz", 391 | "integrity": "sha512-AJEXChcf/nKXd5Q/YLEV5dXQMle3UNT7jcXYmIffZAo/KI394a+/24PaISyQjoNC0fkzS1Q8T5pnGGHmXiVz2g==", 392 | "dependencies": { 393 | "@polkadot/wasm-util": "7.3.2", 394 | "tslib": "^2.6.2" 395 | }, 396 | "engines": { 397 | "node": ">=18" 398 | }, 399 | "peerDependencies": { 400 | "@polkadot/util": "*", 401 | "@polkadot/x-randomvalues": "*" 402 | } 403 | }, 404 | "node_modules/@polkadot/wasm-crypto": { 405 | "version": "7.3.2", 406 | "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.3.2.tgz", 407 | "integrity": "sha512-+neIDLSJ6jjVXsjyZ5oLSv16oIpwp+PxFqTUaZdZDoA2EyFRQB8pP7+qLsMNk+WJuhuJ4qXil/7XiOnZYZ+wxw==", 408 | "dependencies": { 409 | "@polkadot/wasm-bridge": "7.3.2", 410 | "@polkadot/wasm-crypto-asmjs": "7.3.2", 411 | "@polkadot/wasm-crypto-init": "7.3.2", 412 | "@polkadot/wasm-crypto-wasm": "7.3.2", 413 | "@polkadot/wasm-util": "7.3.2", 414 | "tslib": "^2.6.2" 415 | }, 416 | "engines": { 417 | "node": ">=18" 418 | }, 419 | "peerDependencies": { 420 | "@polkadot/util": "*", 421 | "@polkadot/x-randomvalues": "*" 422 | } 423 | }, 424 | "node_modules/@polkadot/wasm-crypto-asmjs": { 425 | "version": "7.3.2", 426 | "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.3.2.tgz", 427 | "integrity": "sha512-QP5eiUqUFur/2UoF2KKKYJcesc71fXhQFLT3D4ZjG28Mfk2ZPI0QNRUfpcxVQmIUpV5USHg4geCBNuCYsMm20Q==", 428 | "dependencies": { 429 | "tslib": "^2.6.2" 430 | }, 431 | "engines": { 432 | "node": ">=18" 433 | }, 434 | "peerDependencies": { 435 | "@polkadot/util": "*" 436 | } 437 | }, 438 | "node_modules/@polkadot/wasm-crypto-init": { 439 | "version": "7.3.2", 440 | "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.3.2.tgz", 441 | "integrity": "sha512-FPq73zGmvZtnuJaFV44brze3Lkrki3b4PebxCy9Fplw8nTmisKo9Xxtfew08r0njyYh+uiJRAxPCXadkC9sc8g==", 442 | "dependencies": { 443 | "@polkadot/wasm-bridge": "7.3.2", 444 | "@polkadot/wasm-crypto-asmjs": "7.3.2", 445 | "@polkadot/wasm-crypto-wasm": "7.3.2", 446 | "@polkadot/wasm-util": "7.3.2", 447 | "tslib": "^2.6.2" 448 | }, 449 | "engines": { 450 | "node": ">=18" 451 | }, 452 | "peerDependencies": { 453 | "@polkadot/util": "*", 454 | "@polkadot/x-randomvalues": "*" 455 | } 456 | }, 457 | "node_modules/@polkadot/wasm-crypto-wasm": { 458 | "version": "7.3.2", 459 | "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.3.2.tgz", 460 | "integrity": "sha512-15wd0EMv9IXs5Abp1ZKpKKAVyZPhATIAHfKsyoWCEFDLSOA0/K0QGOxzrAlsrdUkiKZOq7uzSIgIDgW8okx2Mw==", 461 | "dependencies": { 462 | "@polkadot/wasm-util": "7.3.2", 463 | "tslib": "^2.6.2" 464 | }, 465 | "engines": { 466 | "node": ">=18" 467 | }, 468 | "peerDependencies": { 469 | "@polkadot/util": "*" 470 | } 471 | }, 472 | "node_modules/@polkadot/wasm-util": { 473 | "version": "7.3.2", 474 | "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.3.2.tgz", 475 | "integrity": "sha512-bmD+Dxo1lTZyZNxbyPE380wd82QsX+43mgCm40boyKrRppXEyQmWT98v/Poc7chLuskYb6X8IQ6lvvK2bGR4Tg==", 476 | "dependencies": { 477 | "tslib": "^2.6.2" 478 | }, 479 | "engines": { 480 | "node": ">=18" 481 | }, 482 | "peerDependencies": { 483 | "@polkadot/util": "*" 484 | } 485 | }, 486 | "node_modules/@polkadot/x-bigint": { 487 | "version": "12.6.2", 488 | "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.6.2.tgz", 489 | "integrity": "sha512-HSIk60uFPX4GOFZSnIF7VYJz7WZA7tpFJsne7SzxOooRwMTWEtw3fUpFy5cYYOeLh17/kHH1Y7SVcuxzVLc74Q==", 490 | "dependencies": { 491 | "@polkadot/x-global": "12.6.2", 492 | "tslib": "^2.6.2" 493 | }, 494 | "engines": { 495 | "node": ">=18" 496 | } 497 | }, 498 | "node_modules/@polkadot/x-fetch": { 499 | "version": "12.6.2", 500 | "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.6.2.tgz", 501 | "integrity": "sha512-8wM/Z9JJPWN1pzSpU7XxTI1ldj/AfC8hKioBlUahZ8gUiJaOF7K9XEFCrCDLis/A1BoOu7Ne6WMx/vsJJIbDWw==", 502 | "dependencies": { 503 | "@polkadot/x-global": "12.6.2", 504 | "node-fetch": "^3.3.2", 505 | "tslib": "^2.6.2" 506 | }, 507 | "engines": { 508 | "node": ">=18" 509 | } 510 | }, 511 | "node_modules/@polkadot/x-global": { 512 | "version": "12.6.2", 513 | "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.6.2.tgz", 514 | "integrity": "sha512-a8d6m+PW98jmsYDtAWp88qS4dl8DyqUBsd0S+WgyfSMtpEXu6v9nXDgPZgwF5xdDvXhm+P0ZfVkVTnIGrScb5g==", 515 | "dependencies": { 516 | "tslib": "^2.6.2" 517 | }, 518 | "engines": { 519 | "node": ">=18" 520 | } 521 | }, 522 | "node_modules/@polkadot/x-randomvalues": { 523 | "version": "12.6.2", 524 | "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.6.2.tgz", 525 | "integrity": "sha512-Vr8uG7rH2IcNJwtyf5ebdODMcr0XjoCpUbI91Zv6AlKVYOGKZlKLYJHIwpTaKKB+7KPWyQrk4Mlym/rS7v9feg==", 526 | "dependencies": { 527 | "@polkadot/x-global": "12.6.2", 528 | "tslib": "^2.6.2" 529 | }, 530 | "engines": { 531 | "node": ">=18" 532 | }, 533 | "peerDependencies": { 534 | "@polkadot/util": "12.6.2", 535 | "@polkadot/wasm-util": "*" 536 | } 537 | }, 538 | "node_modules/@polkadot/x-textdecoder": { 539 | "version": "12.6.2", 540 | "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.6.2.tgz", 541 | "integrity": "sha512-M1Bir7tYvNappfpFWXOJcnxUhBUFWkUFIdJSyH0zs5LmFtFdbKAeiDXxSp2Swp5ddOZdZgPac294/o2TnQKN1w==", 542 | "dependencies": { 543 | "@polkadot/x-global": "12.6.2", 544 | "tslib": "^2.6.2" 545 | }, 546 | "engines": { 547 | "node": ">=18" 548 | } 549 | }, 550 | "node_modules/@polkadot/x-textencoder": { 551 | "version": "12.6.2", 552 | "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.6.2.tgz", 553 | "integrity": "sha512-4N+3UVCpI489tUJ6cv3uf0PjOHvgGp9Dl+SZRLgFGt9mvxnvpW/7+XBADRMtlG4xi5gaRK7bgl5bmY6OMDsNdw==", 554 | "dependencies": { 555 | "@polkadot/x-global": "12.6.2", 556 | "tslib": "^2.6.2" 557 | }, 558 | "engines": { 559 | "node": ">=18" 560 | } 561 | }, 562 | "node_modules/@polkadot/x-ws": { 563 | "version": "12.6.2", 564 | "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.6.2.tgz", 565 | "integrity": "sha512-cGZWo7K5eRRQCRl2LrcyCYsrc3lRbTlixZh3AzgU8uX4wASVGRlNWi/Hf4TtHNe1ExCDmxabJzdIsABIfrr7xw==", 566 | "dependencies": { 567 | "@polkadot/x-global": "12.6.2", 568 | "tslib": "^2.6.2", 569 | "ws": "^8.15.1" 570 | }, 571 | "engines": { 572 | "node": ">=18" 573 | } 574 | }, 575 | "node_modules/@scure/base": { 576 | "version": "1.1.6", 577 | "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", 578 | "integrity": "sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==", 579 | "funding": { 580 | "url": "https://paulmillr.com/funding/" 581 | } 582 | }, 583 | "node_modules/@slack/logger": { 584 | "version": "4.0.0", 585 | "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-4.0.0.tgz", 586 | "integrity": "sha512-Wz7QYfPAlG/DR+DfABddUZeNgoeY7d1J39OCR2jR+v7VBsB8ezulDK5szTnDDPDwLH5IWhLvXIHlCFZV7MSKgA==", 587 | "dependencies": { 588 | "@types/node": ">=18.0.0" 589 | }, 590 | "engines": { 591 | "node": ">= 18", 592 | "npm": ">= 8.6.0" 593 | } 594 | }, 595 | "node_modules/@slack/types": { 596 | "version": "2.11.0", 597 | "resolved": "https://registry.npmjs.org/@slack/types/-/types-2.11.0.tgz", 598 | "integrity": "sha512-UlIrDWvuLaDly3QZhCPnwUSI/KYmV1N9LyhuH6EDKCRS1HWZhyTG3Ja46T3D0rYfqdltKYFXbJSSRPwZpwO0cQ==", 599 | "engines": { 600 | "node": ">= 12.13.0", 601 | "npm": ">= 6.12.0" 602 | } 603 | }, 604 | "node_modules/@slack/web-api": { 605 | "version": "7.0.4", 606 | "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-7.0.4.tgz", 607 | "integrity": "sha512-21tbte7N8itwjG7nsiQbDmXP9T/oqEILuvyL2UtgaZxfSY4a1JWWsLGL5n/hcgS2WE2oxmEHsBuhuRkZDwDovw==", 608 | "dependencies": { 609 | "@slack/logger": "^4.0.0", 610 | "@slack/types": "^2.9.0", 611 | "@types/node": ">=18.0.0", 612 | "@types/retry": "0.12.0", 613 | "axios": "^1.6.5", 614 | "eventemitter3": "^5.0.1", 615 | "form-data": "^4.0.0", 616 | "is-electron": "2.2.2", 617 | "is-stream": "^2", 618 | "p-queue": "^6", 619 | "p-retry": "^4", 620 | "retry": "^0.13.1" 621 | }, 622 | "engines": { 623 | "node": ">= 18", 624 | "npm": ">= 8.6.0" 625 | } 626 | }, 627 | "node_modules/@substrate/connect": { 628 | "version": "0.8.10", 629 | "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.10.tgz", 630 | "integrity": "sha512-DIyQ13DDlXqVFnLV+S6/JDgiGowVRRrh18kahieJxhgvzcWicw5eLc6jpfQ0moVVLBYkO7rctB5Wreldwpva8w==", 631 | "optional": true, 632 | "dependencies": { 633 | "@substrate/connect-extension-protocol": "^2.0.0", 634 | "@substrate/connect-known-chains": "^1.1.4", 635 | "@substrate/light-client-extension-helpers": "^0.0.6", 636 | "smoldot": "2.0.22" 637 | } 638 | }, 639 | "node_modules/@substrate/connect-extension-protocol": { 640 | "version": "2.0.0", 641 | "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.0.0.tgz", 642 | "integrity": "sha512-nKu8pDrE3LNCEgJjZe1iGXzaD6OSIDD4Xzz/yo4KO9mQ6LBvf49BVrt4qxBFGL6++NneLiWUZGoh+VSd4PyVIg==", 643 | "optional": true 644 | }, 645 | "node_modules/@substrate/connect-known-chains": { 646 | "version": "1.1.5", 647 | "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.1.5.tgz", 648 | "integrity": "sha512-GCdDMs5q9xDYyP/KEwrlWMdqv8OIPjuVMZvNowvUrvEFo5d+x+VqfRPzyl/RbV+snRQVWTTacRydE7GqyjCYPQ==", 649 | "optional": true 650 | }, 651 | "node_modules/@substrate/light-client-extension-helpers": { 652 | "version": "0.0.6", 653 | "resolved": "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-0.0.6.tgz", 654 | "integrity": "sha512-girltEuxQ1BvkJWmc8JJlk4ZxnlGXc/wkLcNguhY+UoDEMBK0LsdtfzQKIfrIehi4QdeSBlFEFBoI4RqPmsZzA==", 655 | "optional": true, 656 | "dependencies": { 657 | "@polkadot-api/json-rpc-provider": "0.0.1", 658 | "@polkadot-api/json-rpc-provider-proxy": "0.0.1", 659 | "@polkadot-api/observable-client": "0.1.0", 660 | "@polkadot-api/substrate-client": "0.0.1", 661 | "@substrate/connect-extension-protocol": "^2.0.0", 662 | "@substrate/connect-known-chains": "^1.1.4", 663 | "rxjs": "^7.8.1" 664 | }, 665 | "peerDependencies": { 666 | "smoldot": "2.x" 667 | } 668 | }, 669 | "node_modules/@substrate/ss58-registry": { 670 | "version": "1.48.0", 671 | "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.48.0.tgz", 672 | "integrity": "sha512-lE9TGgtd93fTEIoHhSdtvSFBoCsvTbqiCvQIMvX4m6BO/hESywzzTzTFMVP1doBwDDMAN4lsMfIM3X3pdmt7kQ==" 673 | }, 674 | "node_modules/@types/bn.js": { 675 | "version": "5.1.5", 676 | "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", 677 | "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", 678 | "dependencies": { 679 | "@types/node": "*" 680 | } 681 | }, 682 | "node_modules/@types/node": { 683 | "version": "20.14.2", 684 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", 685 | "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", 686 | "dependencies": { 687 | "undici-types": "~5.26.4" 688 | } 689 | }, 690 | "node_modules/@types/retry": { 691 | "version": "0.12.0", 692 | "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", 693 | "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" 694 | }, 695 | "node_modules/asynckit": { 696 | "version": "0.4.0", 697 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 698 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 699 | }, 700 | "node_modules/axios": { 701 | "version": "1.6.8", 702 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", 703 | "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", 704 | "dependencies": { 705 | "follow-redirects": "^1.15.6", 706 | "form-data": "^4.0.0", 707 | "proxy-from-env": "^1.1.0" 708 | } 709 | }, 710 | "node_modules/bn.js": { 711 | "version": "5.2.1", 712 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", 713 | "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" 714 | }, 715 | "node_modules/combined-stream": { 716 | "version": "1.0.8", 717 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 718 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 719 | "dependencies": { 720 | "delayed-stream": "~1.0.0" 721 | }, 722 | "engines": { 723 | "node": ">= 0.8" 724 | } 725 | }, 726 | "node_modules/data-uri-to-buffer": { 727 | "version": "4.0.1", 728 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", 729 | "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", 730 | "engines": { 731 | "node": ">= 12" 732 | } 733 | }, 734 | "node_modules/debug": { 735 | "version": "4.3.5", 736 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 737 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 738 | "dependencies": { 739 | "ms": "2.1.2" 740 | }, 741 | "engines": { 742 | "node": ">=6.0" 743 | }, 744 | "peerDependenciesMeta": { 745 | "supports-color": { 746 | "optional": true 747 | } 748 | } 749 | }, 750 | "node_modules/delayed-stream": { 751 | "version": "1.0.0", 752 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 753 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 754 | "engines": { 755 | "node": ">=0.4.0" 756 | } 757 | }, 758 | "node_modules/eventemitter3": { 759 | "version": "5.0.1", 760 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", 761 | "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" 762 | }, 763 | "node_modules/fetch-blob": { 764 | "version": "3.2.0", 765 | "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", 766 | "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", 767 | "funding": [ 768 | { 769 | "type": "github", 770 | "url": "https://github.com/sponsors/jimmywarting" 771 | }, 772 | { 773 | "type": "paypal", 774 | "url": "https://paypal.me/jimmywarting" 775 | } 776 | ], 777 | "dependencies": { 778 | "node-domexception": "^1.0.0", 779 | "web-streams-polyfill": "^3.0.3" 780 | }, 781 | "engines": { 782 | "node": "^12.20 || >= 14.13" 783 | } 784 | }, 785 | "node_modules/follow-redirects": { 786 | "version": "1.15.6", 787 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", 788 | "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", 789 | "funding": [ 790 | { 791 | "type": "individual", 792 | "url": "https://github.com/sponsors/RubenVerborgh" 793 | } 794 | ], 795 | "engines": { 796 | "node": ">=4.0" 797 | }, 798 | "peerDependenciesMeta": { 799 | "debug": { 800 | "optional": true 801 | } 802 | } 803 | }, 804 | "node_modules/form-data": { 805 | "version": "4.0.0", 806 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 807 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 808 | "dependencies": { 809 | "asynckit": "^0.4.0", 810 | "combined-stream": "^1.0.8", 811 | "mime-types": "^2.1.12" 812 | }, 813 | "engines": { 814 | "node": ">= 6" 815 | } 816 | }, 817 | "node_modules/formdata-polyfill": { 818 | "version": "4.0.10", 819 | "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", 820 | "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", 821 | "dependencies": { 822 | "fetch-blob": "^3.1.2" 823 | }, 824 | "engines": { 825 | "node": ">=12.20.0" 826 | } 827 | }, 828 | "node_modules/is-electron": { 829 | "version": "2.2.2", 830 | "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", 831 | "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==" 832 | }, 833 | "node_modules/is-stream": { 834 | "version": "2.0.1", 835 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", 836 | "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", 837 | "engines": { 838 | "node": ">=8" 839 | }, 840 | "funding": { 841 | "url": "https://github.com/sponsors/sindresorhus" 842 | } 843 | }, 844 | "node_modules/json-stringify-safe": { 845 | "version": "5.0.1", 846 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 847 | "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" 848 | }, 849 | "node_modules/mime-db": { 850 | "version": "1.52.0", 851 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 852 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 853 | "engines": { 854 | "node": ">= 0.6" 855 | } 856 | }, 857 | "node_modules/mime-types": { 858 | "version": "2.1.35", 859 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 860 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 861 | "dependencies": { 862 | "mime-db": "1.52.0" 863 | }, 864 | "engines": { 865 | "node": ">= 0.6" 866 | } 867 | }, 868 | "node_modules/mock-socket": { 869 | "version": "9.3.1", 870 | "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz", 871 | "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==", 872 | "engines": { 873 | "node": ">= 8" 874 | } 875 | }, 876 | "node_modules/ms": { 877 | "version": "2.1.2", 878 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 879 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 880 | }, 881 | "node_modules/nock": { 882 | "version": "13.5.4", 883 | "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", 884 | "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", 885 | "dependencies": { 886 | "debug": "^4.1.0", 887 | "json-stringify-safe": "^5.0.1", 888 | "propagate": "^2.0.0" 889 | }, 890 | "engines": { 891 | "node": ">= 10.13" 892 | } 893 | }, 894 | "node_modules/node-domexception": { 895 | "version": "1.0.0", 896 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 897 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 898 | "funding": [ 899 | { 900 | "type": "github", 901 | "url": "https://github.com/sponsors/jimmywarting" 902 | }, 903 | { 904 | "type": "github", 905 | "url": "https://paypal.me/jimmywarting" 906 | } 907 | ], 908 | "engines": { 909 | "node": ">=10.5.0" 910 | } 911 | }, 912 | "node_modules/node-fetch": { 913 | "version": "3.3.2", 914 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", 915 | "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", 916 | "dependencies": { 917 | "data-uri-to-buffer": "^4.0.0", 918 | "fetch-blob": "^3.1.4", 919 | "formdata-polyfill": "^4.0.10" 920 | }, 921 | "engines": { 922 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 923 | }, 924 | "funding": { 925 | "type": "opencollective", 926 | "url": "https://opencollective.com/node-fetch" 927 | } 928 | }, 929 | "node_modules/p-finally": { 930 | "version": "1.0.0", 931 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 932 | "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", 933 | "engines": { 934 | "node": ">=4" 935 | } 936 | }, 937 | "node_modules/p-queue": { 938 | "version": "6.6.2", 939 | "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", 940 | "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", 941 | "dependencies": { 942 | "eventemitter3": "^4.0.4", 943 | "p-timeout": "^3.2.0" 944 | }, 945 | "engines": { 946 | "node": ">=8" 947 | }, 948 | "funding": { 949 | "url": "https://github.com/sponsors/sindresorhus" 950 | } 951 | }, 952 | "node_modules/p-queue/node_modules/eventemitter3": { 953 | "version": "4.0.7", 954 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", 955 | "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" 956 | }, 957 | "node_modules/p-retry": { 958 | "version": "4.6.2", 959 | "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", 960 | "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", 961 | "dependencies": { 962 | "@types/retry": "0.12.0", 963 | "retry": "^0.13.1" 964 | }, 965 | "engines": { 966 | "node": ">=8" 967 | } 968 | }, 969 | "node_modules/p-timeout": { 970 | "version": "3.2.0", 971 | "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", 972 | "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", 973 | "dependencies": { 974 | "p-finally": "^1.0.0" 975 | }, 976 | "engines": { 977 | "node": ">=8" 978 | } 979 | }, 980 | "node_modules/propagate": { 981 | "version": "2.0.1", 982 | "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", 983 | "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", 984 | "engines": { 985 | "node": ">= 8" 986 | } 987 | }, 988 | "node_modules/proxy-from-env": { 989 | "version": "1.1.0", 990 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 991 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 992 | }, 993 | "node_modules/retry": { 994 | "version": "0.13.1", 995 | "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", 996 | "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", 997 | "engines": { 998 | "node": ">= 4" 999 | } 1000 | }, 1001 | "node_modules/rxjs": { 1002 | "version": "7.8.1", 1003 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", 1004 | "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", 1005 | "dependencies": { 1006 | "tslib": "^2.1.0" 1007 | } 1008 | }, 1009 | "node_modules/scale-ts": { 1010 | "version": "1.6.0", 1011 | "resolved": "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.0.tgz", 1012 | "integrity": "sha512-Ja5VCjNZR8TGKhUumy9clVVxcDpM+YFjAnkMuwQy68Hixio3VRRvWdE3g8T/yC+HXA0ZDQl2TGyUmtmbcVl40Q==", 1013 | "optional": true 1014 | }, 1015 | "node_modules/smoldot": { 1016 | "version": "2.0.22", 1017 | "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.22.tgz", 1018 | "integrity": "sha512-B50vRgTY6v3baYH6uCgL15tfaag5tcS2o/P5q1OiXcKGv1axZDfz2dzzMuIkVpyMR2ug11F6EAtQlmYBQd292g==", 1019 | "optional": true, 1020 | "dependencies": { 1021 | "ws": "^8.8.1" 1022 | } 1023 | }, 1024 | "node_modules/tslib": { 1025 | "version": "2.6.3", 1026 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", 1027 | "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" 1028 | }, 1029 | "node_modules/typescript": { 1030 | "version": "5.4.5", 1031 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 1032 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 1033 | "bin": { 1034 | "tsc": "bin/tsc", 1035 | "tsserver": "bin/tsserver" 1036 | }, 1037 | "engines": { 1038 | "node": ">=14.17" 1039 | } 1040 | }, 1041 | "node_modules/undici-types": { 1042 | "version": "5.26.5", 1043 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1044 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 1045 | }, 1046 | "node_modules/web-streams-polyfill": { 1047 | "version": "3.3.3", 1048 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", 1049 | "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", 1050 | "engines": { 1051 | "node": ">= 8" 1052 | } 1053 | }, 1054 | "node_modules/ws": { 1055 | "version": "8.17.0", 1056 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", 1057 | "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", 1058 | "engines": { 1059 | "node": ">=10.0.0" 1060 | }, 1061 | "peerDependencies": { 1062 | "bufferutil": "^4.0.1", 1063 | "utf-8-validate": ">=5.0.2" 1064 | }, 1065 | "peerDependenciesMeta": { 1066 | "bufferutil": { 1067 | "optional": true 1068 | }, 1069 | "utf-8-validate": { 1070 | "optional": true 1071 | } 1072 | } 1073 | } 1074 | } 1075 | } 1076 | --------------------------------------------------------------------------------