Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
cc4c2cd
feat(api): manual updates
stainless-app[bot] May 7, 2026
21d6894
codegen metadata
stainless-app[bot] May 8, 2026
5ed45a4
fix(gen): resolve lint errors in generated models (#2)
lucasloisp May 9, 2026
6dcc2eb
chore(test): print test names via TESTOPTS=-v in scripts/test (#3)
lucasloisp May 9, 2026
7ffbbc6
feat(client): Privy::PrivyClient wraps generated Privy::Client (#4)
lucasloisp May 9, 2026
8a7255f
feat(authorization): P-256 signing, RFC 8785 canonicalization, prepar…
lucasloisp May 9, 2026
5ce5202
test(integration): ownerless wallet create + rpc against live staging…
lucasloisp May 9, 2026
4686712
test(integration): opt-in HTTP tracing via PRIVY_LOG_HTTP=1 (#7)
lucasloisp May 9, 2026
9866b15
test(integration): P-256 owned wallet personal_sign (happy path + wro…
lucasloisp May 9, 2026
ace5249
docs: add CLAUDE.md with repo conventions and pitfalls (#9)
lucasloisp May 9, 2026
d03a736
feat(services): wallets create/update/rpc auto-inject auth + idempote…
lucasloisp May 9, 2026
bcceffe
ci(integration): run bundle exec rake test:integration on PRs (#11)
lucasloisp May 9, 2026
318b652
feat(authorization): add JwtExchangeService with HPKE encryption (#12)
jagtejsodhi May 13, 2026
2e7947d
ci: add branch-target and pr-title workflows (#32)
lucasloisp May 13, 2026
86b4216
ci(integration): enable verbose output to log each test by name (#31)
lucasloisp May 13, 2026
8f096f7
refactor: consolidate Privy::Authorization::Crypto into Privy::Crypto…
jagtejsodhi May 13, 2026
0ee0513
refactor: rename authorization methods for cross-SDK consistency (#15)
jagtejsodhi May 13, 2026
dfedc4e
feat(authorization): add user_jwts support to AuthorizationContext (#16)
jagtejsodhi May 13, 2026
0fef5d2
refactor: rename prepare → prepare_request, align with Node SDK (#17)
jagtejsodhi May 13, 2026
575ccf4
refactor(wallets): convert create/update/rpc to explicit kwargs inter…
jagtejsodhi May 13, 2026
b4f1d1c
feat(wallets): add raw_sign and transfer convenience wrappers (#18)
jagtejsodhi May 13, 2026
f789358
refactor: move signed_url and merge_prepared_headers to Authorization…
jagtejsodhi May 13, 2026
4fb79c0
feat(policies): add create convenience wrapper with idempotency suppo…
jagtejsodhi May 13, 2026
94da7b6
feat(policies): add update convenience wrapper with authorization sup…
jagtejsodhi May 14, 2026
7cfc41b
feat(policies): add delete convenience wrapper with authorization sup…
jagtejsodhi May 14, 2026
87d1511
feat(policies): add create_rule convenience wrapper with authorizatio…
jagtejsodhi May 14, 2026
39ee81d
feat(policies): add update_rule convenience wrapper with authorizatio…
jagtejsodhi May 14, 2026
88b4f02
feat(policies): add delete_rule convenience wrapper with authorizatio…
jagtejsodhi May 14, 2026
ff985f6
feat(key_quorums): add create convenience wrapper with kwargs interfa…
jagtejsodhi May 14, 2026
4a472e1
feat(key_quorums): add update convenience wrapper with authorization …
jagtejsodhi May 14, 2026
cce679b
feat(key_quorums): add delete convenience wrapper with authorization …
jagtejsodhi May 14, 2026
1abe573
fix: classes resulting from intersections cannot have union parents
stainless-app[bot] May 14, 2026
43c983a
feat(api): api update
stainless-app[bot] May 11, 2026
b7efbbc
feat(api): api update
stainless-app[bot] May 12, 2026
bfc5bc6
ci: pin GitHub Actions to commit SHAs
stainless-app[bot] May 13, 2026
6741307
fix(client): elide content type header on requests without body
stainless-app[bot] May 13, 2026
f93e451
feat(users): add create convenience wrapper with kwargs interface (#33)
lucasloisp May 14, 2026
a6ae14b
fix(integration-tests): isolate user data per test run (#41)
lucasloisp May 14, 2026
518b72d
test: fix client.users.create call (#43)
lucasloisp May 14, 2026
b27c0dd
fix: rename gem to privy_ruby (#44)
lucasloisp May 14, 2026
df65372
feat(public_api): add PrivyRequestExpiryOptions config struct (#34)
lucasloisp May 14, 2026
19ac733
feat(public_api): PrivyClient#compute_request_expiry resolver (#35)
lucasloisp May 14, 2026
f8e1074
feat(wallets): request_expiry kwarg on update/rpc/raw_sign/transfer (…
lucasloisp May 14, 2026
0966ac3
feat(policies): request_expiry kwarg on update/delete/*_rule (#37)
lucasloisp May 14, 2026
afd9886
refactor(public_api): drop content-type workarounds now obsolete (#42)
lucasloisp May 14, 2026
50aebac
feat(key_quorums): request_expiry kwarg on update/delete (#38)
lucasloisp May 14, 2026
45a2459
test(integration): live-backend coverage for request_expiry (#39)
lucasloisp May 14, 2026
e5b543b
docs: document request-expiry configuration; (#40)
lucasloisp May 14, 2026
3369bc7
feat(client): add authorization_key_cache_max_capacity option (#45)
lucasloisp May 14, 2026
49a71ec
release: 0.1.0
stainless-app[bot] May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Values are read in test/privy/integration/integration_test_helper.rb

# Details of the Privy APP used for the integration tests
TEST_APP_ID=
TEST_APP_SECRET=

# Details of the custom auth JWT used for resource ownership
JWT_AUTH_SK=

# Test account details
TEST_APP_TEST_ACCOUNT_OTP=
76 changes: 76 additions & 0 deletions .github/workflows/branch-target.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Branch Target

on:
pull_request:
types: [opened, reopened, edited, synchronize]

concurrency:
group: branch-target-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
pull-requests: write
contents: read

jobs:
check:
name: check
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- name: Validate base branch and manage sticky comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const MARKER = '<!-- privy-branch-target-check -->';
const EXEMPT_AUTHORS = new Set(['stainless-app[bot]']);

const pr = context.payload.pull_request;
const baseRef = pr.base.ref;
const author = pr.user.login;
const isExempt = EXEMPT_AUTHORS.has(author);
const targetsMain = baseRef === 'main';
const shouldFail = targetsMain && !isExempt;

const { owner, repo } = context.repo;
const issue_number = pr.number;

const comments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number, per_page: 100 },
);
const existing = comments.find(
c => c.user?.login === 'github-actions[bot]' && c.body?.includes(MARKER),
);

if (shouldFail) {
const body = [
`:warning: **This PR targets \`${baseRef}\`.**`,
'',
'Feature branches in this SDK should target `next` — `main` is reserved for release PRs.',
'Please change the base branch to `next` (or another stacked feature branch). If you believe `main` really is the right target, let a maintainer know.',
'',
MARKER,
].join('\n');

if (existing) {
if (existing.body !== body) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
}
} else {
await github.rest.issues.createComment({ owner, repo, issue_number, body });
}

core.setFailed(`PR #${issue_number} targets \`${baseRef}\`. Retarget to \`next\`.`);
return;
}

if (existing) {
await github.rest.issues.deleteComment({ owner, repo, comment_id: existing.id });
}

core.info(
isExempt
? `Author ${author} is exempt; skipping base-ref check.`
: `PR targets \`${baseRef}\`; no action needed.`,
);
112 changes: 112 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: CI
on:
push:
branches:
- '**'
- '!integrated/**'
- '!stl-preview-head/**'
- '!stl-preview-base/**'
- '!generated'
- '!codegen/**'
- 'codegen/stl/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
- 'stl-preview-base/**'

jobs:
build:
timeout-minutes: 10
name: build
permissions:
contents: read
id-token: write
runs-on: ${{ github.repository == 'stainless-sdks/privy-api-client-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: |-
github.repository == 'stainless-sdks/privy-api-client-ruby' &&
(github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Ruby
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
with:
bundler-cache: false
- run: |-
bundle install

- name: Get GitHub OIDC Token
if: |-
github.repository == 'stainless-sdks/privy-api-client-ruby' &&
!startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: core.setOutput('github_token', await core.getIDToken());

- name: Build and upload gem artifacts
if: |-
github.repository == 'stainless-sdks/privy-api-client-ruby' &&
!startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
SHA: ${{ github.sha }}
PACKAGE_NAME: privy
run: ./scripts/utils/upload-artifact.sh
lint:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/privy-api-client-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Ruby
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
with:
bundler-cache: false
- run: |-
bundle install

- name: Run lints
run: ./scripts/lint
test:
timeout-minutes: 10
name: test
runs-on: ${{ github.repository == 'stainless-sdks/privy-api-client-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Ruby
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
with:
bundler-cache: false
- run: |-
bundle install

- name: Run tests
run: ./scripts/test
integration:
timeout-minutes: 10
name: integration
runs-on: ${{ github.repository == 'stainless-sdks/privy-api-client-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: |-
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/next')) ||
(github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork)
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: false
- run: |-
bundle install

- name: Run integration tests
env:
TEST_APP_ID: ${{ secrets.TEST_APP_ID }}
TEST_APP_SECRET: ${{ secrets.TEST_APP_SECRET }}
JWT_AUTH_SK: ${{ secrets.JWT_AUTH_SK }}
TEST_APP_TEST_ACCOUNT_OTP: ${{ secrets.TEST_APP_TEST_ACCOUNT_OTP }}
TESTOPTS: "-v"
run: bundle exec rake test:integration
19 changes: 19 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: PR Title
on:
pull_request:
types: [opened, edited, synchronize, reopened]

permissions:
pull-requests: read # Read PR details
contents: read # Read repository content

jobs:
conventional-commits:
timeout-minutes: 5
name: conventional-commits
runs-on: ubuntu-24.04
steps:
- uses: ytanikin/pr-conventional-commits@639145d78959c53c43112365837e3abd21ed67c1
with:
task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert","style","build","release"]'
add_label: 'false'
31 changes: 31 additions & 0 deletions .github/workflows/publish-gem.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This workflow is triggered when a GitHub release is created.
# It can also be run manually to re-publish to rubygems.org in case it failed for some reason.
# You can run this workflow by navigating to https://www.github.com/privy-io/ruby-sdk/actions/workflows/publish-gem.yml
name: Publish Gem
on:
workflow_dispatch:

release:
types: [published]

jobs:
publish:
name: publish
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Ruby
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
with:
bundler-cache: false
- run: |-
bundle install

- name: Publish to RubyGems.org
run: |
bash ./bin/publish-gem
env:
# `RUBYGEMS_HOST` is only required for private gem repositories, not https://rubygems.org
RUBYGEMS_HOST: ${{ secrets.PRIVY_API_RUBYGEMS_HOST || secrets.RUBYGEMS_HOST }}
GEM_HOST_API_KEY: ${{ secrets.PRIVY_API_GEM_HOST_API_KEY || secrets.GEM_HOST_API_KEY }}
22 changes: 22 additions & 0 deletions .github/workflows/release-doctor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Release Doctor
on:
pull_request:
branches:
- main
workflow_dispatch:

jobs:
release_doctor:
name: release doctor
runs-on: ubuntu-latest
if: github.repository == 'privy-io/ruby-sdk' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Check release environment
run: |
bash ./bin/check-release-environment
env:
RUBYGEMS_HOST: ${{ secrets.PRIVY_API_RUBYGEMS_HOST || secrets.RUBYGEMS_HOST }}
GEM_HOST_API_KEY: ${{ secrets.PRIVY_API_GEM_HOST_API_KEY || secrets.GEM_HOST_API_KEY }}
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.gem
.env
.idea/
.ignore
.prism.log
.stdy.log
.ruby-lsp/
.yardoc/
bin/tapioca
Brewfile.lock.json
doc/
sorbet/tapioca/*
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "0.1.0"
}
Loading
Loading