diff --git a/.github/workflows/package-bump.yaml b/.github/workflows/package-bump.yaml index e6a176702..3cafbf70b 100644 --- a/.github/workflows/package-bump.yaml +++ b/.github/workflows/package-bump.yaml @@ -18,24 +18,23 @@ jobs: runs-on: ubuntu-latest steps: - - name: Package bump layer - uses: InjectiveLabs/github-fe/actions/package-bump@master + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 with: - gh_token: ${{ secrets.LAYER_GH_TOKEN }} - repository_url: injectiveLabs/injective-ui - repository_branch: master - - package-bump-layer-tc: - name: 'Package bump layer TC' - runs-on: ubuntu-latest + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-ui + permission-contents: write + permission-pull-requests: write - steps: - - name: Package bump layer TC + - name: Package bump layer uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.LAYER_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: injectiveLabs/injective-ui - repository_branch: feat/tc-layer + repository_branch: master package-bump-hub: name: 'Package bump hub' @@ -43,10 +42,21 @@ jobs: needs: package-bump-layer steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-hub + permission-contents: write + permission-pull-requests: write + - name: Package bump Hub uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.HUB_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: injectiveLabs/injective-hub repository_branch: dev @@ -56,10 +66,21 @@ jobs: needs: package-bump-layer steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-helix + permission-contents: write + permission-pull-requests: write + - name: Package bump Helix uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.HELIX_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: injectiveLabs/injective-helix repository_branch: dev @@ -69,10 +90,21 @@ jobs: needs: package-bump-layer steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-explorer + permission-contents: write + permission-pull-requests: write + - name: Package bump Explorer uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.EXPLORER_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: injectiveLabs/injective-explorer repository_branch: dev @@ -82,25 +114,44 @@ jobs: needs: package-bump-layer steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-trading-ui + permission-contents: write + permission-pull-requests: write + - name: Package bump Trading UI uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.TRADING_UI_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: injectiveLabs/injective-trading-ui repository_branch: dev - package-bump-mito: - name: 'Package bump Mito' - runs-on: ubuntu-latest - needs: package-bump-layer - - steps: - - name: Package bump Mito - uses: InjectiveLabs/github-fe/actions/package-bump@master - with: - gh_token: ${{ secrets.MITO_GH_TOKEN }} - repository_url: mitoFinance/mito-ui - repository_branch: dev + # package-bump-mito: + # name: 'Package bump Mito' + # runs-on: ubuntu-latest + # needs: package-bump-layer + + # steps: + # - name: Create GitHub App token + # id: app-token + # uses: actions/create-github-app-token@v1 + # with: + # app-id: ${{ vars.RELEASE_APP_ID }} + # private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + # owner: mitoFinance + + # - name: Package bump Mito + # uses: InjectiveLabs/github-fe/actions/package-bump@master + # with: + # gh_token: ${{ steps.app-token.outputs.token }} + # repository_url: mitoFinance/mito-ui + # repository_branch: dev package-bump-ui-api: name: 'Package bump UI API' @@ -108,10 +159,21 @@ jobs: needs: package-bump-layer steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-ui-api + permission-contents: write + permission-pull-requests: write + - name: Package bump UI API uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.UI_API_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: injectiveLabs/injective-ui-api repository_branch: staging @@ -121,10 +183,21 @@ jobs: needs: package-bump-layer steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-admin-ui + permission-contents: write + permission-pull-requests: write + - name: Package bump Admin UI uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.ADMIN_UI_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: InjectiveLabs/injective-admin-ui repository_branch: dev @@ -134,22 +207,20 @@ jobs: needs: package-bump-layer steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + owner: InjectiveLabs + repositories: injective-do-ui + permission-contents: write + permission-pull-requests: write + - name: Package bump DO UI uses: InjectiveLabs/github-fe/actions/package-bump@master with: - gh_token: ${{ secrets.DO_UI_GH_TOKEN }} + gh_token: ${{ steps.app-token.outputs.token }} repository_url: injectiveLabs/injective-do-ui repository_branch: master - - package-bump-true-current: - name: 'Package bump True Current' - runs-on: ubuntu-latest - needs: package-bump-layer-tc - - steps: - - name: Package bump True Current - uses: InjectiveLabs/github-fe/actions/package-bump@master - with: - gh_token: ${{ secrets.TRUE_CURRENT_GH_TOKEN }} - repository_url: injectiveLabs/injective-true-current - repository_branch: dev diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 67762b8f9..6bac37e04 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,7 +1,9 @@ name: Publish # Unified publish workflow for all release types: -# - latest: Triggered on push to master branch (npm tag: latest) +# - latest: Triggered from master branch activity (npm tag: latest) +# - Regular master commits prepare or update a release PR +# - The merged "chore: release" commit on master performs the actual publish # - Default: patch bump # - With "release-minor" in commit message: minor bump # - canary: Triggered on feature branches with "canary" in commit message (npm tag: alpha) @@ -31,12 +33,6 @@ concurrency: group: publish-${{ github.repository }} cancel-in-progress: false -# OIDC requires id-token: write permission -# contents: write is needed for git push --follow-tags and creating GitHub Releases -permissions: - contents: write - id-token: write - jobs: # ============================================ # Publish Job - Handles latest, canary, and beta @@ -44,15 +40,18 @@ jobs: publish: name: 'Publish' runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + pull-requests: write # Skip if: - # - Contains skip keywords (for master branch) + # - Contains skip keywords + # - Is the automation-managed release branch # - Is a feature branch without canary/beta keyword and not a workflow_dispatch # - Is workflow_dispatch on master with a non-prod release type if: | !contains(github.event.head_commit.message, 'GITBOOK') && - !contains(github.event.head_commit.message, 'skip-deploy') && - !contains(github.event.head_commit.message, 'skip deploy') && - !startsWith(github.event.head_commit.message, 'chore: release') && + github.ref != 'refs/heads/release/master' && ( github.ref == 'refs/heads/master' || contains(github.event.head_commit.message, 'canary') || @@ -61,18 +60,26 @@ jobs: ) && !(github.ref == 'refs/heads/master' && github.event_name == 'workflow_dispatch' && inputs.release_type != 'prod') outputs: + mode: ${{ steps.determine-publish-type.outputs.mode }} publish_type: ${{ steps.determine-publish-type.outputs.type }} dist_tag: ${{ steps.determine-publish-type.outputs.dist_tag }} version_args: ${{ steps.determine-publish-type.outputs.version_args }} steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - # TS_GH_TOKEN must belong to an actor on the master branch-protection - # bypass list so lerna's version-bump commit can be pushed directly. - token: ${{ secrets.TS_GH_TOKEN }} + token: ${{ steps.app-token.outputs.token }} - name: Using Node from .nvmrc uses: actions/setup-node@v4 @@ -111,7 +118,12 @@ jobs: env: COMMIT_MSG: ${{ github.event.head_commit.message }} BRANCH: ${{ github.ref }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} + REPOSITORY: ${{ github.repository }} + SHA: ${{ github.sha }} run: | + MODE="" + # Handle workflow_dispatch input if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then RELEASE_TYPE="${{ inputs.release_type }}" @@ -120,14 +132,17 @@ jobs: echo "::error::prod releases can only be triggered from the master branch" exit 1 fi + MODE="prepare_release_pr" TYPE="latest" DIST_TAG="latest" - VERSION_ARGS="patch --force-publish --force-git-tag --no-changelog --yes --no-push" + VERSION_ARGS="patch --force-publish --no-changelog --yes --no-push --no-git-tag-version" elif [[ "$RELEASE_TYPE" == "canary" ]]; then + MODE="direct_publish" TYPE="canary" DIST_TAG="alpha" VERSION_ARGS="prerelease --preid alpha --force-publish --force-git-tag --no-changelog --yes --no-push" elif [[ "$RELEASE_TYPE" == "beta" ]]; then + MODE="direct_publish" TYPE="beta" DIST_TAG="beta" VERSION_ARGS="prerelease --preid beta --force-publish --force-git-tag --no-changelog --yes --no-push" @@ -135,6 +150,7 @@ jobs: echo "::error::Unrecognized release_type '$RELEASE_TYPE'" exit 1 fi + echo "mode=$MODE" >> $GITHUB_OUTPUT echo "type=$TYPE" >> $GITHUB_OUTPUT echo "dist_tag=$DIST_TAG" >> $GITHUB_OUTPUT echo "version_args=$VERSION_ARGS" >> $GITHUB_OUTPUT @@ -160,23 +176,40 @@ jobs: # Determine publish type based on branch and commit message if [[ "$BRANCH" == "refs/heads/master" ]]; then - # Determine bump type: minor if "release-minor" keyword, otherwise patch - if [[ "$HAS_RELEASE_MINOR" == "true" ]]; then - BUMP_TYPE="minor" - else - BUMP_TYPE="patch" - fi TYPE="latest" DIST_TAG="latest" - VERSION_ARGS="$BUMP_TYPE --force-publish --force-git-tag --no-changelog --yes --no-push" + + RELEASE_PR_HEAD=$(gh api \ + -H "Accept: application/vnd.github+json" \ + "repos/${REPOSITORY}/commits/${SHA}/pulls" \ + --jq '.[] | select(.merged_at != null and .head.ref == "release/master") | .head.ref' \ + | head -n1) + + if [[ "$RELEASE_PR_HEAD" == "release/master" ]]; then + MODE="publish_release" + VERSION_ARGS="" + else + MODE="prepare_release_pr" + + # Determine bump type: minor if "release-minor" keyword, otherwise patch + if [[ "$HAS_RELEASE_MINOR" == "true" ]]; then + BUMP_TYPE="minor" + else + BUMP_TYPE="patch" + fi + + VERSION_ARGS="$BUMP_TYPE --force-publish --no-changelog --yes --no-push --no-git-tag-version" + fi elif [[ "$HAS_CANARY" == "true" && "$HAS_BETA" == "true" ]]; then echo "::error::Commit message contains both 'canary' and 'beta'. Please use only one." exit 1 elif [[ "$HAS_CANARY" == "true" ]]; then + MODE="direct_publish" TYPE="canary" DIST_TAG="alpha" VERSION_ARGS="prerelease --preid alpha --force-publish --force-git-tag --no-changelog --yes --no-push" elif [[ "$HAS_BETA" == "true" ]]; then + MODE="direct_publish" TYPE="beta" DIST_TAG="beta" VERSION_ARGS="prerelease --preid beta --force-publish --force-git-tag --no-changelog --yes --no-push" @@ -185,6 +218,7 @@ jobs: exit 1 fi + echo "mode=$MODE" >> $GITHUB_OUTPUT echo "type=$TYPE" >> $GITHUB_OUTPUT echo "dist_tag=$DIST_TAG" >> $GITHUB_OUTPUT echo "version_args=$VERSION_ARGS" >> $GITHUB_OUTPUT @@ -202,15 +236,34 @@ jobs: run: pnpm build - name: Version packages + if: steps.determine-publish-type.outputs.mode != 'publish_release' run: | pnpm exec lerna version ${{ steps.determine-publish-type.outputs.version_args }} + - name: Create or update release PR + if: steps.determine-publish-type.outputs.mode == 'prepare_release_pr' + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ steps.app-token.outputs.token }} + branch: release/master + base: master + delete-branch: true + commit-message: 'chore: release' + title: 'chore: release' + body: | + Automated release PR created by the publish workflow. + + Merging this PR will publish the versioned packages from `master`. + author: '${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>' + committer: '${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>' + - name: Push version commits and tags to git + if: steps.determine-publish-type.outputs.mode == 'direct_publish' run: | git push origin HEAD --follow-tags - name: Create and push release tag - if: github.ref == 'refs/heads/master' + if: github.ref == 'refs/heads/master' && steps.determine-publish-type.outputs.mode == 'publish_release' run: | VERSION=$(node -p "require('./packages/sdk-ts/package.json').version") TAG="v${VERSION}" @@ -224,6 +277,7 @@ jobs: # pnpm pack resolves catalog: protocol, npm publish handles OIDC authentication - name: Publish to npm (OIDC) + if: steps.determine-publish-type.outputs.mode != 'prepare_release_pr' run: | DIST_TAG="${{ steps.determine-publish-type.outputs.dist_tag }}" PUBLISHED_PACKAGES="[]" @@ -263,6 +317,7 @@ jobs: echo "✅ Successfully published $PUBLISH_COUNT packages" - name: Broadcast published versions on Slack + if: steps.determine-publish-type.outputs.mode != 'prepare_release_pr' run: node etc/slack.cjs --api="$SLACK_API" --actor="$GIT_ACTOR" --commit-message="$GIT_LATEST_COMMIT_MESSAGE" env: GIT_ACTOR: ${{ github.actor }} @@ -274,9 +329,9 @@ jobs: # step fails, retry manually with: # gh release create vX.Y.Z --title vX.Y.Z --notes "..." --latest --verify-tag - name: Create GitHub Release - if: github.ref == 'refs/heads/master' + if: github.ref == 'refs/heads/master' && steps.determine-publish-type.outputs.mode == 'publish_release' env: - GH_TOKEN: ${{ secrets.TS_GH_TOKEN }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | VERSION=$(node -p "require('./packages/sdk-ts/package.json').version") TAG="v${VERSION}" @@ -315,6 +370,6 @@ jobs: trigger-package-bumps: name: 'Trigger Package Bumps' needs: publish - if: needs.publish.result == 'success' && needs.publish.outputs.publish_type == 'latest' + if: needs.publish.result == 'success' && needs.publish.outputs.publish_type == 'latest' && needs.publish.outputs.mode == 'publish_release' uses: ./.github/workflows/package-bump.yaml secrets: inherit diff --git a/packages/exceptions/package.json b/packages/exceptions/package.json index aea26519c..f9cb604c3 100644 --- a/packages/exceptions/package.json +++ b/packages/exceptions/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/exceptions", - "version": "1.20.20", + "version": "1.20.23", "description": "List of exceptions that can be reused throughout Injective's projects.", "license": "Apache-2.0", "author": { diff --git a/packages/networks/package.json b/packages/networks/package.json index a48638986..ca0fd10ac 100644 --- a/packages/networks/package.json +++ b/packages/networks/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/networks", - "version": "1.20.20", + "version": "1.20.23", "description": "Endpoints, networks, etc. Can be reused throughout Injective's projects.", "license": "Apache-2.0", "author": { diff --git a/packages/sdk-ts/package.json b/packages/sdk-ts/package.json index e281e6248..f94d74cc7 100644 --- a/packages/sdk-ts/package.json +++ b/packages/sdk-ts/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/sdk-ts", - "version": "1.20.20", + "version": "1.20.23", "description": "SDK in TypeScript for building Injective applications in a browser, node, and react native environment.", "license": "Apache-2.0", "author": { diff --git a/packages/ts-types/package.json b/packages/ts-types/package.json index 73eb6b190..9177156ae 100644 --- a/packages/ts-types/package.json +++ b/packages/ts-types/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/ts-types", - "version": "1.20.20", + "version": "1.20.23", "description": "List of types that can be reused throughout Injective.", "license": "Apache-2.0", "author": { diff --git a/packages/utils/package.json b/packages/utils/package.json index 7eb7c91da..606f7d107 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/utils", - "version": "1.20.20", + "version": "1.20.23", "description": "List of utils and helper functions that can be reused throughout Injective's projects.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-base/package.json b/packages/wallets/wallet-base/package.json index 0a008a1cf..d94946e7a 100644 --- a/packages/wallets/wallet-base/package.json +++ b/packages/wallets/wallet-base/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-base", - "version": "1.20.20", + "version": "1.20.23", "description": "Base wallet strategy for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-core/package.json b/packages/wallets/wallet-core/package.json index 52c89093c..806e55a37 100644 --- a/packages/wallets/wallet-core/package.json +++ b/packages/wallets/wallet-core/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-core", - "version": "1.20.20", + "version": "1.20.23", "description": "Core wallet strategy", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-cosmos-strategy/package.json b/packages/wallets/wallet-cosmos-strategy/package.json index 7c33c0761..c6d204bdd 100644 --- a/packages/wallets/wallet-cosmos-strategy/package.json +++ b/packages/wallets/wallet-cosmos-strategy/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-cosmos-strategy", - "version": "1.20.20", + "version": "1.20.23", "description": "Wallet Cosmos Strategy with instantiated wallets", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-cosmos/package.json b/packages/wallets/wallet-cosmos/package.json index 08d96d989..205565e14 100644 --- a/packages/wallets/wallet-cosmos/package.json +++ b/packages/wallets/wallet-cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-cosmos", - "version": "1.20.20", + "version": "1.20.23", "description": "Cosmos wallet strategies for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-cosmostation/package.json b/packages/wallets/wallet-cosmostation/package.json index 985acdf30..de984288d 100644 --- a/packages/wallets/wallet-cosmostation/package.json +++ b/packages/wallets/wallet-cosmostation/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-cosmostation", - "version": "1.20.20", + "version": "1.20.23", "description": "Cosmostation strategy for use with @injectivelabs/wallet-core.", "deprecated": "Use @injectivelabs/wallet-cosmos with Wallet.Cosmostation instead", "license": "Apache-2.0", diff --git a/packages/wallets/wallet-evm/package.json b/packages/wallets/wallet-evm/package.json index 407273acf..553a890b4 100644 --- a/packages/wallets/wallet-evm/package.json +++ b/packages/wallets/wallet-evm/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-evm", - "version": "1.20.20", + "version": "1.20.23", "description": "EVM wallet strategies for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-ledger/package.json b/packages/wallets/wallet-ledger/package.json index 25b54f4da..8d18db3bd 100644 --- a/packages/wallets/wallet-ledger/package.json +++ b/packages/wallets/wallet-ledger/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-ledger", - "version": "1.20.20", + "version": "1.20.23", "description": "Ledger wallet strategy for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-magic/package.json b/packages/wallets/wallet-magic/package.json index 833d7f620..6845424e4 100644 --- a/packages/wallets/wallet-magic/package.json +++ b/packages/wallets/wallet-magic/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-magic", - "version": "1.20.20", + "version": "1.20.23", "description": "Magic wallet strategy for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-private-key/package.json b/packages/wallets/wallet-private-key/package.json index dd876e33a..bb08b8aa1 100644 --- a/packages/wallets/wallet-private-key/package.json +++ b/packages/wallets/wallet-private-key/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-private-key", - "version": "1.20.20", + "version": "1.20.23", "description": "Private key wallet strategy for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-strategy/package.json b/packages/wallets/wallet-strategy/package.json index e86ff278c..36953fb56 100644 --- a/packages/wallets/wallet-strategy/package.json +++ b/packages/wallets/wallet-strategy/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-strategy", - "version": "1.20.20", + "version": "1.20.23", "description": "Wallet strategy with instantiated wallets", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-trezor/package.json b/packages/wallets/wallet-trezor/package.json index 573f9a4ee..4fef12172 100644 --- a/packages/wallets/wallet-trezor/package.json +++ b/packages/wallets/wallet-trezor/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-trezor", - "version": "1.20.20", + "version": "1.20.23", "description": "Trezor wallet strategy for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-turnkey/package.json b/packages/wallets/wallet-turnkey/package.json index 49875094e..d623a202b 100644 --- a/packages/wallets/wallet-turnkey/package.json +++ b/packages/wallets/wallet-turnkey/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-turnkey", - "version": "1.20.20", + "version": "1.20.23", "description": "Turnkey wallet strategy for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": { diff --git a/packages/wallets/wallet-turnkey/src/index.ts b/packages/wallets/wallet-turnkey/src/index.ts index 79ff5d369..960efa946 100644 --- a/packages/wallets/wallet-turnkey/src/index.ts +++ b/packages/wallets/wallet-turnkey/src/index.ts @@ -1,3 +1,4 @@ +export * from './strategy/types.js' export * from './strategy/strategy.js' export * from './strategy/turnkey/turnkey.js' diff --git a/packages/wallets/wallet-turnkey/src/strategy/turnkey/oauth.ts b/packages/wallets/wallet-turnkey/src/strategy/turnkey/oauth.ts index 63e7d165e..77e2449ae 100644 --- a/packages/wallets/wallet-turnkey/src/strategy/turnkey/oauth.ts +++ b/packages/wallets/wallet-turnkey/src/strategy/turnkey/oauth.ts @@ -11,7 +11,7 @@ import { import type { HttpRestClient } from '@injectivelabs/utils' import type { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser' import type { TurnkeyOAuthProvider } from '@injectivelabs/wallet-base' -import type { TurnkeyOauthLoginResponse } from '../types.js' +import type { TurnkeyOauthAuthenticatedResponse } from '../types.js' export class TurnkeyOauthWallet { static async generateOAuthNonce(indexedDbClient: TurnkeyIndexedDbClient) { @@ -42,9 +42,7 @@ export class TurnkeyOauthWallet { providerName: TurnkeyOAuthProvider indexedDbClient: TurnkeyIndexedDbClient expirationSeconds?: number - }): Promise< - { organizationId: string; credentialBundle: string } | undefined - > { + }): Promise { const { client, indexedDbClient, expirationSeconds } = args const path = args.oauthLoginPath || TURNKEY_OAUTH_PATH @@ -57,7 +55,7 @@ export class TurnkeyOauthWallet { } // client.$post is undefined, resorting to this for now const response = await client.post<{ - data: TurnkeyOauthLoginResponse + data: TurnkeyOauthAuthenticatedResponse }>(path, { targetPublicKey, oidcToken: args.oidcToken, diff --git a/packages/wallets/wallet-turnkey/src/strategy/turnkey/turnkey.ts b/packages/wallets/wallet-turnkey/src/strategy/turnkey/turnkey.ts index 9c9cb6198..782588a91 100644 --- a/packages/wallets/wallet-turnkey/src/strategy/turnkey/turnkey.ts +++ b/packages/wallets/wallet-turnkey/src/strategy/turnkey/turnkey.ts @@ -29,6 +29,11 @@ import type { TurnkeyMetadata, TurnkeyOAuthProvider, } from '@injectivelabs/wallet-base' +import type { + TurnkeyOauthProvider, + TurnkeyOAuth2ConfirmResponse, + TurnkeyOAuth2AuthenticatedResponse, +} from '../types.js' export class TurnkeyWallet { private otpId?: string @@ -359,7 +364,10 @@ export class TurnkeyWallet { ) } - public async confirmOAuth(provider: TurnkeyOAuthProvider, oidcToken: string) { + public async confirmOAuth( + provider: TurnkeyOAuthProvider, + oidcToken: string, + ): Promise { if (provider === TurnkeyProvider.Apple) { throw new WalletException( new Error('Apple sign in option is currently not supported'), @@ -376,7 +384,7 @@ export class TurnkeyWallet { oauthLoginPath: this.metadata.oauthLoginPath || TURNKEY_OAUTH_PATH, }) - if (!oauthResult || !oauthResult.credentialBundle) { + if (!oauthResult?.credentialBundle) { throw new WalletException(new Error('Unexpected OAuth result')) } @@ -398,27 +406,65 @@ export class TurnkeyWallet { codeVerifier: string targetPublicKey: string providerName: TurnkeyOAuthProvider - }) { + }): Promise { const indexedDbClient = await this.getIndexedDbClient() const path = this.metadata.oauth2ExchangePath || 'turnkey/oauth2' const response = await this.client.post<{ - data: { credentialBundle: string; organizationId: string; email?: string } + data: TurnkeyOAuth2AuthenticatedResponse }>(path, { nonce, authCode, codeVerifier, targetPublicKey, providerName }) - if (!response?.data?.credentialBundle || !response?.data?.organizationId) { + const responseData = response?.data + const credentialBundle = + responseData?.credentialBundle ?? responseData?.session + const organizationId = responseData?.organizationId + + if (!credentialBundle || !organizationId) { throw new WalletException( new Error(`${providerName} OAuth2 exchange failed`), ) } - const { credentialBundle, organizationId, email } = response.data + const { email, userName, profileImageUrl } = responseData await indexedDbClient.loginWithSession(credentialBundle) this.userOrganizationId = organizationId - return { session: credentialBundle, email } + return { session: credentialBundle, email, userName, profileImageUrl } + } + + public async getCurrentOauthProviders(): Promise { + const indexedDbClient = await this.getIndexedDbClient() + const { organizationId } = await this.getSession() + + if (!organizationId) { + throw new WalletException( + new Error('Turnkey organization not found. Please login again.'), + ) + } + + const user = await indexedDbClient.getWhoami({ organizationId }) + let userId = user?.userId + + if (!userId) { + const { users } = await indexedDbClient.getUsers({ organizationId }) + + if (users.length !== 1) { + throw new WalletException( + new Error('Unable to resolve current Turnkey user.'), + ) + } + + userId = users[0].userId + } + + const { oauthProviders } = await indexedDbClient.getOauthProviders({ + organizationId, + userId, + }) + + return oauthProviders } public async refreshSession() { diff --git a/packages/wallets/wallet-turnkey/src/strategy/types.ts b/packages/wallets/wallet-turnkey/src/strategy/types.ts index 18f8ab58e..b3f18fde2 100644 --- a/packages/wallets/wallet-turnkey/src/strategy/types.ts +++ b/packages/wallets/wallet-turnkey/src/strategy/types.ts @@ -38,8 +38,32 @@ export type TurnkeyConfirmEmailOTPResponse = { organizationId: string } -export type TurnkeyOauthLoginResponse = { +export type TurnkeyOauthAuthenticatedResponse = { + message?: string organizationId: string credentialBundle: string - message: string +} + +export type TurnkeyOAuth2AuthenticatedResponse = { + email?: string + session?: string + userName?: string + profileImageUrl?: string + organizationId: string + credentialBundle?: string +} + +export type TurnkeyOAuth2ConfirmResponse = { + email?: string + session: string + userName?: string + profileImageUrl?: string +} + +export type TurnkeyOauthProvider = { + issuer: string + subject: string + audience: string + providerId: string + providerName: string } diff --git a/packages/wallets/wallet-wallet-connect/package.json b/packages/wallets/wallet-wallet-connect/package.json index 9d927ad77..1186b37cf 100644 --- a/packages/wallets/wallet-wallet-connect/package.json +++ b/packages/wallets/wallet-wallet-connect/package.json @@ -1,6 +1,6 @@ { "name": "@injectivelabs/wallet-wallet-connect", - "version": "1.20.20", + "version": "1.20.23", "description": "Wallet connect strategy for use with @injectivelabs/wallet-core.", "license": "Apache-2.0", "author": {