Skip to content

Commit 09d6760

Browse files
paulbalajiantigremlincursoragent
authored
feat: starknet-sdk w/ artifact api (#8158)
Co-authored-by: Andrey Taranov <86911+antigremlin@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Paul Balaji <paulbalaji@users.noreply.github.com>
1 parent cc6d57b commit 09d6760

98 files changed

Lines changed: 9696 additions & 241 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@hyperlane-xyz/starknet-sdk': minor
3+
'@hyperlane-xyz/deploy-sdk': minor
4+
'@hyperlane-xyz/cli': minor
5+
---
6+
7+
Added Starknet artifact API support across the TypeScript AltVM toolchain. The new `@hyperlane-xyz/starknet-sdk` package provides Starknet protocol, signer, provider, ISM, hook, mailbox, validator announce, and end-to-end test coverage. Deploy SDK protocol loading and the CLI context/signer flows were updated so Starknet chains can be resolved and used through the shared AltVM paths.

.github/workflows/test-sdk-e2e.yml

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ on:
99
type: string
1010
has_radix:
1111
type: string
12+
has_starknet:
13+
type: string
1214
has_tron:
1315
type: string
1416
has_svm:
@@ -34,7 +36,7 @@ jobs:
3436
- name: pnpm-build
3537
uses: ./.github/actions/pnpm-build-with-cache
3638
with:
37-
build-filter: '@hyperlane-xyz/cosmos-sdk...'
39+
build-filter: "@hyperlane-xyz/cosmos-sdk..."
3840

3941
- name: Cosmos SDK e2e tests
4042
run: pnpm -C typescript/cosmos-sdk test:e2e
@@ -67,7 +69,7 @@ jobs:
6769
- name: pnpm-build
6870
uses: ./.github/actions/pnpm-build-with-cache
6971
with:
70-
build-filter: '@hyperlane-xyz/aleo-sdk...'
72+
build-filter: "@hyperlane-xyz/aleo-sdk..."
7173

7274
- name: Aleo SDK e2e tests (${{ matrix.test }})
7375
run: pnpm -C typescript/aleo-sdk test:e2e
@@ -87,11 +89,41 @@ jobs:
8789
- name: pnpm-build
8890
uses: ./.github/actions/pnpm-build-with-cache
8991
with:
90-
build-filter: '@hyperlane-xyz/radix-sdk...'
92+
build-filter: "@hyperlane-xyz/radix-sdk..."
9193

9294
- name: Radix SDK e2e tests
9395
run: pnpm -C typescript/radix-sdk test:e2e
9496

97+
starknet-sdk-e2e-matrix:
98+
runs-on: depot-ubuntu-24.04
99+
if: inputs.has_starknet == 'true'
100+
timeout-minutes: 15
101+
strategy:
102+
fail-fast: false
103+
matrix:
104+
test:
105+
- ism
106+
- mailbox
107+
- hook
108+
- validator_announce
109+
- warp_core
110+
- warp_transfer
111+
steps:
112+
- uses: actions/checkout@v6
113+
with:
114+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
115+
submodules: recursive
116+
persist-credentials: false
117+
- name: pnpm-build
118+
uses: ./.github/actions/pnpm-build-with-cache
119+
with:
120+
build-filter: "@hyperlane-xyz/starknet-sdk..."
121+
122+
- name: Starknet SDK e2e tests (${{ matrix.test }})
123+
run: pnpm -C typescript/starknet-sdk test:e2e
124+
env:
125+
STARKNET_SDK_E2E_TEST: ${{ matrix.test }}
126+
95127
tron-sdk-e2e-run:
96128
runs-on: depot-ubuntu-24.04
97129
if: inputs.has_tron == 'true'
@@ -106,7 +138,7 @@ jobs:
106138
- name: pnpm-build
107139
uses: ./.github/actions/pnpm-build-with-cache
108140
with:
109-
build-filter: '@hyperlane-xyz/tron-sdk...'
141+
build-filter: "@hyperlane-xyz/tron-sdk..."
110142

111143
- name: Tron SDK e2e tests with coverage
112144
run: pnpm -C typescript/tron-sdk coverage
@@ -149,7 +181,7 @@ jobs:
149181
- name: pnpm-build
150182
uses: ./.github/actions/pnpm-build-with-cache
151183
with:
152-
build-filter: '@hyperlane-xyz/sealevel-sdk...'
184+
build-filter: "@hyperlane-xyz/sealevel-sdk..."
153185

154186
- name: SVM SDK e2e tests (${{ matrix.test }})
155187
run: pnpm -C typescript/svm-sdk test:e2e

.github/workflows/test.yml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ name: test
33
on:
44
# Triggers the workflow on pushes to main branch
55
push:
6-
branches: [main, 'audit-*']
6+
branches: [main, "audit-*"]
77
# Triggers on pull requests
88
pull_request:
99
branches:
10-
- '*'
10+
- "*"
1111
merge_group:
1212
workflow_dispatch:
1313

@@ -111,7 +111,7 @@ jobs:
111111
- name: Check lint-prettier status
112112
uses: ./.github/actions/check-job-status
113113
with:
114-
job_name: 'Lint Prettier'
114+
job_name: "Lint Prettier"
115115
result: ${{ needs.lint-prettier-run.result }}
116116

117117
set-base-sha:
@@ -140,6 +140,7 @@ jobs:
140140
has_cosmos: ${{ steps.decide.outputs.has_cosmos }}
141141
has_aleo: ${{ steps.decide.outputs.has_aleo }}
142142
has_radix: ${{ steps.decide.outputs.has_radix }}
143+
has_starknet: ${{ steps.decide.outputs.has_starknet }}
143144
has_tron: ${{ steps.decide.outputs.has_tron }}
144145
has_relayer: ${{ steps.decide.outputs.has_relayer }}
145146
has_rebalancer: ${{ steps.decide.outputs.has_rebalancer }}
@@ -165,7 +166,7 @@ jobs:
165166
base_sha: ${{ needs.set-base-sha.outputs.base_sha }}
166167
head_sha: ${{ needs.set-base-sha.outputs.current_sha }}
167168
path_pattern: '(rust/|\.github/|typescript/Dockerfile|typescript/docker-entrypoint\.sh)'
168-
path_pattern_only: 'true'
169+
path_pattern_only: "true"
169170

170171
- name: Categorize changes for CLI e2e and VM detection
171172
id: check-vm
@@ -179,6 +180,7 @@ jobs:
179180
echo "has_radix=true" >> $GITHUB_OUTPUT
180181
echo "has_aleo=true" >> $GITHUB_OUTPUT
181182
echo "has_cosmos=true" >> $GITHUB_OUTPUT
183+
echo "has_starknet=true" >> $GITHUB_OUTPUT
182184
echo "has_tron=true" >> $GITHUB_OUTPUT
183185
echo "has_relayer=true" >> $GITHUB_OUTPUT
184186
echo "has_rebalancer=true" >> $GITHUB_OUTPUT
@@ -191,6 +193,7 @@ jobs:
191193
echo "has_radix=false" >> $GITHUB_OUTPUT
192194
echo "has_aleo=false" >> $GITHUB_OUTPUT
193195
echo "has_cosmos=false" >> $GITHUB_OUTPUT
196+
echo "has_starknet=false" >> $GITHUB_OUTPUT
194197
echo "has_tron=false" >> $GITHUB_OUTPUT
195198
echo "has_relayer=false" >> $GITHUB_OUTPUT
196199
echo "has_rebalancer=false" >> $GITHUB_OUTPUT
@@ -202,6 +205,7 @@ jobs:
202205
has_radix=$(echo "$CHANGED_FILES" | grep -qE '^typescript/radix-sdk/' && echo true || echo false)
203206
has_aleo=$(echo "$CHANGED_FILES" | grep -qE '^typescript/aleo-sdk/' && echo true || echo false)
204207
has_cosmos=$(echo "$CHANGED_FILES" | grep -qE '^typescript/(cosmos-sdk|cosmos-types)/' && echo true || echo false)
208+
has_starknet=$(echo "$CHANGED_FILES" | grep -qE '^(typescript/(starknet-sdk|provider-sdk|utils)/|starknet/)' && echo true || echo false)
205209
has_tron=$(echo "$CHANGED_FILES" | grep -qE '^typescript/tron-sdk/' && echo true || echo false)
206210
has_svm=$(echo "$CHANGED_FILES" | grep -qE '^(rust/sealevel/|typescript/svm-sdk/)' && echo true || echo false)
207211
@@ -219,16 +223,17 @@ jobs:
219223
echo "has_radix=$has_radix" >> $GITHUB_OUTPUT
220224
echo "has_aleo=$has_aleo" >> $GITHUB_OUTPUT
221225
echo "has_cosmos=$has_cosmos" >> $GITHUB_OUTPUT
226+
echo "has_starknet=$has_starknet" >> $GITHUB_OUTPUT
222227
echo "has_tron=$has_tron" >> $GITHUB_OUTPUT
223228
echo "has_relayer=$has_relayer" >> $GITHUB_OUTPUT
224229
echo "has_rebalancer=$has_rebalancer" >> $GITHUB_OUTPUT
225230
226231
echo "CLI changes: $has_cli_changes"
227-
echo "VM-specific — radix=$has_radix aleo=$has_aleo cosmos=$has_cosmos tron=$has_tron"
232+
echo "VM-specific — radix=$has_radix aleo=$has_aleo cosmos=$has_cosmos starknet=$has_starknet tron=$has_tron"
228233
echo "Package-specific — relayer=$has_relayer rebalancer=$has_rebalancer"
229234
echo "has_svm=$has_svm" >> $GITHUB_OUTPUT
230235
231-
echo "VM-specific — radix=$has_radix aleo=$has_aleo cosmos=$has_cosmos tron=$has_tron svm=$has_svm"
236+
echo "VM-specific — radix=$has_radix aleo=$has_aleo cosmos=$has_cosmos starknet=$has_starknet tron=$has_tron svm=$has_svm"
232237
233238
- name: Decide what to run
234239
id: decide
@@ -248,6 +253,7 @@ jobs:
248253
echo "has_cosmos=false" >> $GITHUB_OUTPUT
249254
echo "has_aleo=false" >> $GITHUB_OUTPUT
250255
echo "has_radix=false" >> $GITHUB_OUTPUT
256+
echo "has_starknet=false" >> $GITHUB_OUTPUT
251257
echo "has_tron=false" >> $GITHUB_OUTPUT
252258
echo "has_relayer=false" >> $GITHUB_OUTPUT
253259
echo "has_rebalancer=false" >> $GITHUB_OUTPUT
@@ -262,6 +268,7 @@ jobs:
262268
echo "has_cosmos=true" >> $GITHUB_OUTPUT
263269
echo "has_aleo=true" >> $GITHUB_OUTPUT
264270
echo "has_radix=true" >> $GITHUB_OUTPUT
271+
echo "has_starknet=true" >> $GITHUB_OUTPUT
265272
echo "has_tron=true" >> $GITHUB_OUTPUT
266273
echo "has_relayer=true" >> $GITHUB_OUTPUT
267274
echo "has_rebalancer=true" >> $GITHUB_OUTPUT
@@ -275,6 +282,7 @@ jobs:
275282
echo "has_cosmos=${{ steps.check-vm.outputs.has_cosmos }}" >> $GITHUB_OUTPUT
276283
echo "has_aleo=${{ steps.check-vm.outputs.has_aleo }}" >> $GITHUB_OUTPUT
277284
echo "has_radix=${{ steps.check-vm.outputs.has_radix }}" >> $GITHUB_OUTPUT
285+
echo "has_starknet=${{ steps.check-vm.outputs.has_starknet }}" >> $GITHUB_OUTPUT
278286
echo "has_tron=${{ steps.check-vm.outputs.has_tron }}" >> $GITHUB_OUTPUT
279287
echo "has_relayer=${{ steps.check-vm.outputs.has_relayer }}" >> $GITHUB_OUTPUT
280288
echo "has_rebalancer=${{ steps.check-vm.outputs.has_rebalancer }}" >> $GITHUB_OUTPUT
@@ -309,7 +317,7 @@ jobs:
309317
- name: Check pnpm-test status
310318
uses: ./.github/actions/check-job-status
311319
with:
312-
job_name: 'PNPM Test'
320+
job_name: "PNPM Test"
313321
result: ${{ needs.pnpm-test-run.result }}
314322

315323
infra-test:
@@ -391,7 +399,7 @@ jobs:
391399
- name: Check cli-install-test status
392400
uses: ./.github/actions/check-job-status
393401
with:
394-
job_name: 'CLI Install Test'
402+
job_name: "CLI Install Test"
395403
result: ${{ needs.cli-install-test-run.result }}
396404

397405
# Reusable workflow callers
@@ -419,7 +427,7 @@ jobs:
419427
- name: Check CLI E2E status
420428
uses: ./.github/actions/check-job-status
421429
with:
422-
job_name: 'CLI E2E'
430+
job_name: "CLI E2E"
423431
result: ${{ needs.cli-e2e-tests.result }}
424432

425433
sdk-e2e-tests:
@@ -430,6 +438,7 @@ jobs:
430438
has_cosmos: ${{ needs.change-detection.outputs.has_cosmos }}
431439
has_aleo: ${{ needs.change-detection.outputs.has_aleo }}
432440
has_radix: ${{ needs.change-detection.outputs.has_radix }}
441+
has_starknet: ${{ needs.change-detection.outputs.has_starknet }}
433442
has_tron: ${{ needs.change-detection.outputs.has_tron }}
434443
has_svm: ${{ needs.change-detection.outputs.has_svm }}
435444

@@ -442,7 +451,7 @@ jobs:
442451
- name: Check SDK E2E status
443452
uses: ./.github/actions/check-job-status
444453
with:
445-
job_name: 'SDK E2E'
454+
job_name: "SDK E2E"
446455
result: ${{ needs.sdk-e2e-tests.result }}
447456

448457
rust-e2e-tests:

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ COPY typescript/rebalancer-sim/package.json ./typescript/rebalancer-sim/
4444
COPY typescript/relayer/package.json ./typescript/relayer/
4545
COPY typescript/sdk/package.json ./typescript/sdk/
4646
COPY typescript/svm-sdk/package.json ./typescript/svm-sdk/
47+
COPY typescript/starknet-sdk/package.json ./typescript/starknet-sdk/
4748
COPY typescript/tsconfig/package.json ./typescript/tsconfig/
4849
COPY typescript/utils/package.json ./typescript/utils/
4950
COPY typescript/metrics/package.json ./typescript/metrics/

pnpm-lock.yaml

Lines changed: 73 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

starknet/scripts/StarknetArtifactGenerator.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ export class StarknetArtifactGenerator {
4747
*/
4848
async getArtifactPaths() {
4949
const sierraPattern = `${this.compiledContractsDir}/**/*${CONTRACT_SUFFIXES.SIERRA_JSON}`;
50+
const casmPattern = `${this.compiledContractsDir}/**/*${CONTRACT_SUFFIXES.ASSEMBLY_JSON}`;
5051
const sierraFiles = await globby(sierraPattern);
51-
return { sierraFiles };
52+
const casmFiles = await globby(casmPattern);
53+
return { sierraFiles, casmFiles };
5254
}
5355

5456
/**
@@ -74,19 +76,18 @@ export class StarknetArtifactGenerator {
7476
artifact: any,
7577
contractClass: ContractClass,
7678
) {
77-
// For Sierra contracts, extract the ABI if the file contains contract_class in its name
7879
if (contractClass === ContractClass.SIERRA) {
79-
const abiOnly: CompiledContract = {
80-
sierra_program: [],
81-
contract_class_version: artifact.contract_class_version,
82-
entry_points_by_type: artifact.entry_points_by_type,
80+
// Full Sierra data is required downstream for Starknet class-hash and deployment paths.
81+
// ABI-only artifacts break ContractFactory usage in @hyperlane-xyz/starknet-sdk.
82+
const compiledContract: CompiledContract = {
83+
...artifact,
8384
abi:
8485
typeof artifact.abi === 'string'
8586
? JSON.parse(artifact.abi)
8687
: artifact.abi,
8788
};
8889

89-
return Templates.jsArtifact(name, abiOnly);
90+
return Templates.jsArtifact(name, compiledContract);
9091
}
9192
// For other contract types, return the full artifact
9293
return Templates.jsArtifact(name, artifact);
@@ -236,10 +237,13 @@ export class StarknetArtifactGenerator {
236237
async generate(): Promise<ReadonlyProcessedFilesMap> {
237238
await this.createOutputDirectory();
238239

239-
const { sierraFiles } = await this.getArtifactPaths();
240+
const { sierraFiles, casmFiles } = await this.getArtifactPaths();
241+
const artifactFiles = [...sierraFiles, ...casmFiles].sort((a, b) =>
242+
a.localeCompare(b),
243+
);
240244

241245
const processingResults = await Promise.all(
242-
sierraFiles.map((file) => this.processArtifact(file)),
246+
artifactFiles.map((file) => this.processArtifact(file)),
243247
);
244248

245249
const processedFilesMap =

0 commit comments

Comments
 (0)