Skip to content

Commit 2318777

Browse files
committed
Merge branch 'master' into 0xlucca/add-collectives
2 parents 75fbb98 + 572c2b7 commit 2318777

File tree

50 files changed

+1657
-450
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1657
-450
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import requests
2+
import json
3+
import sys
4+
import yaml
5+
from urllib.parse import urlparse
6+
7+
REGISTRIES = {
8+
"repositories": lambda info: get_latest_github_release(info.get("repository_url")),
9+
"crates": lambda info: get_latest_crate_version(info.get("name")),
10+
"javascript_packages": lambda info: get_latest_npm_version(info.get("name")),
11+
"python_packages": lambda info: get_latest_pypi_version(info.get("name")),
12+
}
13+
14+
def get_latest_github_release(repo_url):
15+
try:
16+
path = urlparse(repo_url).path.strip("/")
17+
owner, repo = path.split("/")[-2:]
18+
api_url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
19+
response = requests.get(api_url)
20+
if response.status_code == 200:
21+
data = response.json()
22+
return data["tag_name"], data["html_url"]
23+
except Exception as e:
24+
print(f"Error fetching GitHub release for {repo_url}: {e}")
25+
return None, None
26+
27+
def get_latest_crate_version(crate_name):
28+
try:
29+
response = requests.get(f"https://crates.io/api/v1/crates/{crate_name}")
30+
if response.status_code == 200:
31+
data = response.json()["crate"]
32+
latest_version = data["max_stable_version"]
33+
return latest_version, f"https://crates.io/crates/{crate_name}/{latest_version}"
34+
except Exception as e:
35+
print(f"Error fetching crate version for {crate_name}: {e}")
36+
return None, None
37+
38+
def get_latest_npm_version(package_name):
39+
try:
40+
response = requests.get(f"https://registry.npmjs.org/{package_name}")
41+
if response.status_code == 200:
42+
data = response.json()
43+
latest_version = data["dist-tags"]["latest"]
44+
return latest_version, f"https://www.npmjs.com/package/{package_name}/v/{latest_version}"
45+
except Exception as e:
46+
print(f"Error fetching npm package version for {package_name}: {e}")
47+
return None, None
48+
49+
def get_latest_pypi_version(package_name):
50+
try:
51+
response = requests.get(f"https://pypi.org/pypi/{package_name}/json")
52+
if response.status_code == 200:
53+
data = response.json()["info"]
54+
latest_version = data["version"]
55+
return latest_version, f"https://pypi.org/project/{package_name}/{latest_version}/"
56+
except Exception as e:
57+
print(f"Error fetching PyPI package version for {package_name}: {e}")
58+
return None, None
59+
60+
def check_releases(releases_source_file):
61+
try:
62+
with open(releases_source_file, "r") as file:
63+
data = yaml.safe_load(file)
64+
dependencies = data.get("dependencies", {})
65+
except Exception as e:
66+
print(f"Error reading releases source file '{releases_source_file}': {e}")
67+
sys.exit(1)
68+
69+
outdated_dependencies = []
70+
71+
for category, items in dependencies.items():
72+
if category not in REGISTRIES:
73+
continue
74+
75+
for name, info in items.items():
76+
current_version = info.get("version")
77+
latest_version, latest_url = REGISTRIES[category](info)
78+
79+
if latest_version and latest_version != current_version:
80+
outdated_dependencies.append({
81+
"name": name,
82+
"category": category,
83+
"current_version": current_version,
84+
"latest_version": latest_version,
85+
"latest_release_url": latest_url,
86+
})
87+
88+
return outdated_dependencies
89+
90+
def main(releases_source_file):
91+
try:
92+
outdated_dependencies = check_releases(releases_source_file)
93+
output = {
94+
"outdated_dependencies": outdated_dependencies,
95+
"outdated_count": len(outdated_dependencies),
96+
}
97+
with open("outdated_dependencies.json", "w") as f:
98+
json.dump(output, f, indent=2)
99+
print(json.dumps(output))
100+
except Exception as e:
101+
print(f"Error in main execution: {e}")
102+
sys.exit(1)
103+
104+
if __name__ == "__main__":
105+
main("variables.yml")

.github/scripts/create_issues.py

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,13 @@
22
import json
33
import os
44
import sys
5-
from urllib.parse import urlparse
65

76
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN")
87

9-
10-
def parse_github_url(url):
11-
"""Extract owner and repo from a GitHub URL."""
12-
try:
13-
path = urlparse(url).path.strip("/")
14-
return path.split("/")[-2:]
15-
except Exception as e:
16-
print(f"Error parsing GitHub URL: {e}")
17-
sys.exit(1)
18-
19-
20-
def issue_exists(owner, repo, title):
8+
def issue_exists(title):
219
"""Check if an issue with the same title already exists."""
2210
try:
23-
url = f"https://api.github.com/repos/polkadot-developers/polkadot-docs/issues"
11+
url = "https://api.github.com/repos/polkadot-developers/polkadot-docs/issues"
2412
headers = {
2513
"Authorization": f"token {GITHUB_TOKEN}",
2614
"Accept": "application/vnd.github.v3+json",
@@ -37,15 +25,14 @@ def issue_exists(owner, repo, title):
3725
print(f"Error checking for existing issues: {e}")
3826
sys.exit(1)
3927

40-
41-
def create_github_issue(owner, repo, title, body):
28+
def create_github_issue(title, body):
4229
"""Create a GitHub issue using the GitHub API."""
4330
try:
44-
if issue_exists(owner, repo, title):
31+
if issue_exists(title):
4532
print(f"Issue '{title}' already exists. Skipping creation.")
4633
return
4734

48-
url = f"https://api.github.com/repos/polkadot-developers/polkadot-docs/issues"
35+
url = "https://api.github.com/repos/polkadot-developers/polkadot-docs/issues"
4936
headers = {
5037
"Authorization": f"token {GITHUB_TOKEN}",
5138
"Accept": "application/vnd.github.v3+json",
@@ -57,41 +44,38 @@ def create_github_issue(owner, repo, title, body):
5744
print(f"Successfully created issue '{title}'")
5845
return
5946
else:
60-
print(
61-
f"Failed to create issue '{title}'. Status code: {response.status_code}"
62-
)
47+
print(f"Failed to create issue '{title}'. Status code: {response.status_code}")
6348
print(response.text)
6449
sys.exit(1)
6550
except Exception as e:
6651
print(f"Error creating issue: {e}")
6752
sys.exit(1)
6853

69-
7054
def main():
71-
# Check if GITHUB_TOKEN is set
7255
if not GITHUB_TOKEN:
7356
print("Error: GITHUB_TOKEN environment variable is not set.")
7457
sys.exit(1)
7558

76-
# Read the JSON file with outdated repositories
7759
try:
78-
with open("outdated_repositories.json", "r") as f:
60+
with open("outdated_dependencies.json", "r") as f:
7961
data = json.load(f)
8062
except Exception as e:
8163
print(f"Error reading JSON file: {e}")
8264
sys.exit(1)
8365

84-
for repo in data.get("outdated_repos", []):
85-
owner, repo_name = parse_github_url(repo["repository"])
86-
title = f"Update needed: {repo_name} ({repo['current_version']} -> {repo['latest_version']})"
87-
body = f"""A new release has been detected for {repo['repository']}.
88-
Current version: {repo['current_version']}
89-
Latest version: {repo['latest_version']}
66+
for dep in data.get("outdated_dependencies", []):
67+
title = f"Update needed: {dep['name']} ({dep['current_version']} -> {dep['latest_version']})"
68+
body = f"""A new release has been detected for {dep['name']}.
9069
91-
Please review the change log and update the documentation accordingly."""
70+
Category: {dep['category']}
71+
Current version: {dep['current_version']}
72+
Latest version: {dep['latest_version']}
9273
93-
create_github_issue(owner, repo_name, title, body)
74+
Latest release: [View here]({dep['latest_release_url']})
75+
76+
Please review the change log and update the documentation accordingly."""
9477

78+
create_github_issue(title, body)
9579

9680
if __name__ == "__main__":
97-
main()
81+
main()
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
name: Check Repositories
1+
name: Check Dependencies
22

33
on:
44
schedule: # Run every day at midnight.
55
- cron: '0 0 * * *'
66
workflow_dispatch: # Allows manual triggering of the workflow.
77

88
jobs:
9-
check-repositories:
9+
check-dependencies:
1010
runs-on: ubuntu-latest
1111
permissions:
1212
issues: write
@@ -24,12 +24,12 @@ jobs:
2424
python -m pip install --upgrade pip
2525
pip install requests pyyaml
2626
27-
- name: Check for Outdated Repositories
28-
id: check_repositories
27+
- name: Check for Outdated Dependencies
28+
id: check_dependencies
2929
run: |
30-
python .github/scripts/check_repositories.py
30+
python .github/scripts/check_dependencies.py
3131
32-
- name: Create GitHub Issues for Outdated Repositories
32+
- name: Create GitHub Issues for Outdated Dependencies
3333
env:
3434
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3535
run: |
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "my-project"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
subxt = "0.39.0"
8+
subxt-signer = "0.39.0"
9+
tokio = { version = "1.43.0", features = ["rt", "macros"] }
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::str::FromStr;
2+
use subxt::utils::AccountId32;
3+
use subxt::{OnlineClient, PolkadotConfig};
4+
use subxt_signer::{bip39::Mnemonic,sr25519::Keypair};
5+
6+
// Generate an interface that we can use from the node's metadata.
7+
#[subxt::subxt(runtime_metadata_path = "./polkadot_metadata.scale")]
8+
pub mod polkadot {}
9+
10+
#[tokio::main(flavor = "current_thread")]
11+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
12+
// Define the node URL.
13+
const NODE_URL: &str = "INSERT_NODE_URL";
14+
15+
// Initialize the Subxt client to interact with the blockchain.
16+
let api = OnlineClient::<PolkadotConfig>::from_url(NODE_URL).await?;
17+
18+
// A query to obtain some constant.
19+
let constant_query = polkadot::constants().balances().existential_deposit();
20+
21+
// Obtain the value.
22+
let value = api.constants().at(&constant_query)?;
23+
24+
println!("Existential deposit: {:?}", value);
25+
26+
// Define the target account address.
27+
const ADDRESS: &str = "INSERT_ADDRESS";
28+
let account = AccountId32::from_str(ADDRESS).unwrap();
29+
30+
// Build a storage query to access account information.
31+
let storage_query = polkadot::storage().system().account(&account.into());
32+
33+
// Fetch the latest state for the account.
34+
let result = api
35+
.storage()
36+
.at_latest()
37+
.await?
38+
.fetch(&storage_query)
39+
.await?
40+
.unwrap();
41+
42+
println!("Account info: {:?}", result);
43+
44+
// Define the recipient address and transfer amount.
45+
const DEST_ADDRESS: &str = "INSERT_DEST_ADDRESS";
46+
const AMOUNT: u128 = INSERT_AMOUNT;
47+
48+
// Convert the recipient address into an `AccountId32`.
49+
let dest = AccountId32::from_str(DEST_ADDRESS).unwrap();
50+
51+
// Build the balance transfer extrinsic.
52+
let balance_transfer_tx = polkadot::tx()
53+
.balances()
54+
.transfer_allow_death(dest.into(), AMOUNT);
55+
56+
// Load the sender's keypair from a mnemonic phrase.
57+
const SECRET_PHRASE: &str = "INSERT_SECRET_PHRASE";
58+
let mnemonic = Mnemonic::parse(SECRET_PHRASE).unwrap();
59+
let sender_keypair = Keypair::from_phrase(&mnemonic, None).unwrap();
60+
61+
// Sign and submit the extrinsic, then wait for it to be finalized.
62+
let events = api
63+
.tx()
64+
.sign_and_submit_then_watch_default(&balance_transfer_tx, &sender_keypair)
65+
.await?
66+
.wait_for_finalized_success()
67+
.await?;
68+
69+
// Check for a successful transfer event.
70+
if let Some(event) = events.find_first::<polkadot::balances::events::Transfer>()? {
71+
println!("Balance transfer successful: {:?}", event);
72+
}
73+
74+
Ok(())
75+
}

.snippets/code/develop/toolkit/interoperability/asset-transfer-api/reference/tx-result.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,6 @@ A promise containing the result of constructing the transaction.
133133

134134
The `ConstructedFormat` type is a conditional type that returns a specific type based on the value of the TxResult `format` field.
135135

136-
- **Payload format** - if the format field is set to `'payload'`, the `ConstructedFormat` type will return a [`GenericExtrinsicPayload`](https://github.com/polkadot-js/api/blob/{{ dependencies.polkadot_js_api.version}}/packages/types/src/extrinsic/ExtrinsicPayload.ts#L83){target=\_blank}
136+
- **Payload format** - if the format field is set to `'payload'`, the `ConstructedFormat` type will return a [`GenericExtrinsicPayload`](https://github.com/polkadot-js/api/blob/{{ dependencies.repositories.polkadot_js_api.version}}/packages/types/src/extrinsic/ExtrinsicPayload.ts#L83){target=\_blank}
137137
- **Call format** - if the format field is set to `'call'`, the `ConstructedFormat` type will return a hexadecimal string (`0x${string}`). This is the encoded representation of the extrinsic call
138-
- **Submittable format** - if the format field is set to `'submittable'`, the `ConstructedFormat` type will return a [`SubmittableExtrinsic`](https://github.com/polkadot-js/api/blob/{{ dependencies.polkadot_js_api.version}}/packages/api-base/src/types/submittable.ts#L56){target=\_blank}. This is a Polkadot.js type that represents a transaction that can be submitted to the blockchain
138+
- **Submittable format** - if the format field is set to `'submittable'`, the `ConstructedFormat` type will return a [`SubmittableExtrinsic`](https://github.com/polkadot-js/api/blob/{{ dependencies.repositories.polkadot_js_api.version}}/packages/api-base/src/types/submittable.ts#L56){target=\_blank}. This is a Polkadot.js type that represents a transaction that can be submitted to the blockchain
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"bootNodes": [],
3+
"chainType": "Live",
4+
"codeSubstitutes": {},
5+
"genesis": {
6+
"runtimeGenesis": {
7+
"code": "0x...",
8+
"patch": {
9+
"aura": {
10+
"authorities": []
11+
},
12+
"auraExt": {},
13+
"balances": {
14+
"balances": [["INSERT_SUDO_ACCOUNT", 1152921504606846976]]
15+
},
16+
"collatorSelection": {
17+
"candidacyBond": 16000000000,
18+
"desiredCandidates": 0,
19+
"invulnerables": ["INSERT_ACCOUNT_ID_COLLATOR_1"]
20+
},
21+
"parachainInfo": {
22+
"parachainId": "INSERT_PARA_ID"
23+
},
24+
"parachainSystem": {},
25+
"polkadotXcm": {
26+
"safeXcmVersion": 4
27+
},
28+
"session": {
29+
"keys": [
30+
[
31+
"INSERT_ACCOUNT_ID_COLLATOR_1",
32+
"INSERT_ACCOUNT_ID_COLLATOR_1",
33+
{
34+
"aura": "INSERT_SESSION_KEY_COLLATOR_1"
35+
}
36+
]
37+
],
38+
"nonAuthorityKeys": []
39+
},
40+
"sudo": {
41+
"key": "INSERT_SUDO_ACCOUNT"
42+
},
43+
"system": {},
44+
"transactionPayment": {
45+
"multiplier": "1000000000000000000"
46+
}
47+
}
48+
}
49+
},
50+
"id": "INSERT_ID",
51+
"name": "INSERT_NAME",
52+
"para_id": "INSERT_PARA_ID",
53+
"properties": {
54+
"tokenDecimals": 12,
55+
"tokenSymbol": "UNIT"
56+
},
57+
"protocolId": "INSERT_PROTOCOL_ID",
58+
"relay_chain": "paseo",
59+
"telemetryEndpoints": null
60+
}

0 commit comments

Comments
 (0)