diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 75c24185..eb098327 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,7 +20,7 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - submodules: false + submodules: recursive - name: Setup Node.js uses: actions/setup-node@v4 @@ -31,9 +31,6 @@ jobs: - name: Install dependencies run: npm i - - name: Initialize Splice Submodule - run: git submodule update --init --depth 1 libs/splice - - name: Build package run: npm run build diff --git a/.github/workflows/test-cn-quickstart.yml b/.github/workflows/tests.yml similarity index 95% rename from .github/workflows/test-cn-quickstart.yml rename to .github/workflows/tests.yml index ad4e7d75..623adba5 100644 --- a/.github/workflows/test-cn-quickstart.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -name: Test CN-Quickstart Integration +name: Tests on: push: @@ -11,7 +11,7 @@ on: workflow_dispatch: jobs: - test-cn-quickstart: + tests: runs-on: ubuntu-latest timeout-minutes: 60 @@ -19,7 +19,7 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 with: - submodules: false + submodules: recursive - name: Setup Node.js uses: actions/setup-node@v4 @@ -79,12 +79,6 @@ jobs: git commit -m "chore: auto-fix linting issues [skip ci]" git push - - name: Initialize Submodules - if: steps.quickstart-prep-cache-restore.outputs.cache-hit != 'true' - run: | - git submodule update --init --depth 1 libs/splice - git submodule update --init --recursive libs/cn-quickstart - - name: Setup CN-Quickstart if: steps.quickstart-prep-cache-restore.outputs.cache-hit != 'true' run: | diff --git a/.gitmodules b/.gitmodules index 3252bea1..cbdcb616 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "libs/splice"] path = libs/splice url = https://github.com/hyperledger-labs/splice +[submodule "libs/cn-quickstart"] + path = libs/cn-quickstart + url = https://github.com/digital-asset/cn-quickstart diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 6294f9d0..00000000 --- a/examples/README.md +++ /dev/null @@ -1,126 +0,0 @@ -# Canton Node SDK - LocalNet Examples - -Simple examples for connecting to Canton Network LocalNet using the Canton Node SDK. - -## Prerequisites - -- cn-quickstart is running (see https://github.com/digital-asset/cn-quickstart) -- cn-quickstart is configured with OAuth2 enabled -- Dependencies installed: `npm install` - -## Examples - -### `localnet-with-oauth2.ts` - OAuth2 Authentication ✅ - -**Status**: ✅ **Working** - This is the recommended example! - -Demonstrates how to: - -- Connect to cn-quickstart with OAuth2/Keycloak authentication -- Use the SDK's built-in authentication manager -- Make authenticated API calls to the Validator API - -**Run it:** - -```bash -npm run example:oauth2 -``` - -**What it does:** - -1. Authenticates with Keycloak using client credentials -2. Gets an OAuth2 access token -3. Makes an authenticated API call to get user status -4. The SDK handles all token management automatically! - -**Key Features:** - -- ✅ Automatic token acquisition -- ✅ Automatic token refresh when expired -- ✅ Bearer token automatically included in requests -- ✅ No manual token management needed - -### Configuration - -The example uses the default cn-quickstart OAuth2 configuration: - -```typescript -{ - authUrl: 'http://localhost:8082/realms/AppProvider/protocol/openid-connect/token', - apis: { - VALIDATOR_API: { - apiUrl: 'http://localhost:3903', - auth: { - grantType: 'client_credentials', - clientId: 'app-provider-validator', - clientSecret: 'AL8648b9SfdTFImq7FV56Vd0KHifHBuC', - }, - }, - }, -} -``` - -## Try Other API Methods - -Once you have a working client, you can call any Validator API method: - -```typescript -// Get wallet balance -const balance = await client.getWalletBalance(); - -// Get amulets -const amulets = await client.getAmulets(); - -// Get DSO party ID -const dsoPartyId = await client.getDsoPartyId(); - -// Get amulet rules -const rules = await client.getAmuletRules(); - -// List ANS entries -const entries = await client.listAnsEntries(); -``` - -## Next Steps - -1. **Explore the SDK**: Check out the full API documentation at https://sdk.canton.fairmint.com/ -2. **Stream Updates**: See `scripts/examples/` for streaming and subscription examples -3. **Integration Tests**: Look at `test/integration/quickstart/` for more complex examples -4. **Web UIs**: Explore the running services: - - Wallet: http://wallet.localhost:3000 - - Scan: http://scan.localhost:4000 - -## Troubleshooting - -### Authentication Failed - -```bash -# Verify Keycloak is running -curl http://localhost:8082/realms/AppProvider - -# Check cn-quickstart OAuth2 setup -cd quickstart && make setup # Ensure "with OAuth2" is selected -``` - -### Connection Refused - -```bash -# Check if services are running -cd quickstart && make status - -# Restart if needed -cd quickstart && make restart -``` - -### Wrong Credentials - -The credentials in the example (`app-provider-validator` / `AL8648b9SfdTFImq7FV56Vd0KHifHBuC`) are -the default values for cn-quickstart. If you've customized your setup, check: - -- `quickstart/docker/modules/keycloak/env/app-provider/on/oauth2.env` - -## More Resources - -- Main README: `../../examples/README.md` -- SDK Documentation: https://sdk.canton.fairmint.com/ -- cn-quickstart: https://github.com/digital-asset/cn-quickstart diff --git a/examples/localnet-with-oauth2.ts b/examples/localnet-with-oauth2.ts deleted file mode 100644 index 67416fa2..00000000 --- a/examples/localnet-with-oauth2.ts +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env tsx -/** - * Example: Canton Network LocalNet with OAuth2 Authentication - * - * This example demonstrates how to connect to cn-quickstart with OAuth2/Keycloak authentication using the Canton Node - * SDK. - * - * Prerequisites: - * - * - Cn-quickstart is running with OAuth2 enabled - * - Run `cd quickstart && make setup` and choose "with OAuth2" - * - Run `cd quickstart && make start` - * - * The SDK automatically handles: - * - * - OAuth2 token acquisition - * - Token refresh - * - Bearer token injection in API calls - * - * Usage: npx tsx canton-node-sdk/examples/localnet-with-oauth2.ts - */ - -import { LedgerJsonApiClient, ValidatorApiClient } from '../src'; - -async function main(): Promise { - console.log('🔌 Connecting to Canton Network LocalNet with OAuth2...\n'); - - try { - // ✨ Simple configuration! The SDK now has cn-quickstart defaults built-in - // Just specify the network and it automatically configures: - // - OAuth2 auth URL (Keycloak) - // - API endpoints (ports 3903, 3975, etc.) - // - Client credentials (app-provider-validator) - const validatorClient = new ValidatorApiClient({ - network: 'localnet', - }); - - const jsonClient = new LedgerJsonApiClient({ - network: 'localnet', - }); - - console.log('🔐 Authenticating with OAuth2...'); - - // The SDK will automatically call authenticate() before API calls, - // but we can also call it explicitly to test authentication - const token = await validatorClient.authenticate(); - console.log('✅ Authentication successful!'); - console.log(` Token acquired: ${token.substring(0, 50)}...\n`); - - console.log('📡 Calling Validator API: getUserStatus()...'); - - // Make an API call - the SDK automatically includes the bearer token - const userStatus = await validatorClient.getUserStatus(); - - console.log('✅ API call successful!\n'); - console.log('User Status:'); - console.log(JSON.stringify(userStatus, null, 2)); - - console.log('\n✨ Connection test successful!'); - console.log('\n📚 What the SDK did for you with just { network: "localnet" }:'); - console.log(' 1. Auto-configured OAuth2 URL (http://localhost:8082/realms/AppProvider/...)'); - console.log(' 2. Auto-configured API endpoints (Validator: 3903, JSON API: 3975)'); - console.log(' 3. Auto-configured client credentials (app-provider-validator)'); - console.log(' 4. Connected to Keycloak and got access token'); - console.log(' 5. Automatically included Bearer token in all API requests'); - console.log(' 6. Will auto-refresh token when it expires'); - - console.log('\n📡 Testing Ledger JSON API: getVersion()...'); - const version = await jsonClient.getVersion(); - console.log('✅ Ledger JSON API call successful!\n'); - console.log('Ledger API Version:', version.version); - console.log('Features:', JSON.stringify(version.features, null, 2)); - - console.log('\n💡 Next steps:'); - console.log(' - Try other Validator API methods: getWalletBalance(), getAmulets(), etc.'); - console.log(' - Try Ledger JSON API methods: listUsers(), getLedgerEnd(), etc.'); - console.log(' - Check out canton-node-sdk/scripts/examples/ for more examples'); - console.log(' - Explore the web UIs:'); - console.log(' • Wallet: http://wallet.localhost:3000'); - console.log(' • Scan: http://scan.localhost:4000'); - - process.exit(0); - } catch (error) { - console.error('\n❌ Error:'); - if (error instanceof Error) { - console.error(` ${error.message}`); - if (error.message.includes('ECONNREFUSED')) { - console.log('\n💡 Make sure cn-quickstart is running:'); - console.log(' cd quickstart && make start'); - } else if (error.message.includes('401') || error.message.includes('authentication')) { - console.log('\n💡 Authentication failed. This could mean:'); - console.log(' 1. cn-quickstart is not configured with OAuth2'); - console.log(' → Run: cd quickstart && make setup (choose "with OAuth2")'); - console.log(' 2. Keycloak is not accessible'); - console.log(' → Check: http://localhost:8082'); - } - } else { - console.error(error); - } - process.exit(1); - } -} - -// Run the main function -void main(); diff --git a/package.json b/package.json index aac900a2..a85c0e44 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "docs": "tsx scripts/update-docs-version.ts && tsx scripts/generate-operation-docs.ts", "docs:build": "npm run docs && cd docs && bundle exec jekyll build", "docs:dev": "npm run docs && cd docs && bundle exec jekyll serve --livereload --port 4000", - "example:connect": "tsx examples/localnet-with-oauth2.ts", "fix": "npm run lint:fix && npm run format:fix", "format": "prettier --check .", "format:fix": "prettier --write .", diff --git a/tsconfig.lint.json b/tsconfig.lint.json index 54180ee0..b52c5bce 100644 --- a/tsconfig.lint.json +++ b/tsconfig.lint.json @@ -4,6 +4,6 @@ "rootDir": ".", "outDir": "./build" }, - "include": ["src/**/*", "test/**/*", "scripts/**/*", "examples/**/*"], + "include": ["src/**/*", "test/**/*", "scripts/**/*"], "exclude": ["**/*.example.ts"] }