mixin_bot 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d03bd8cb9d6710487b3ef3c5ed57e88136a0bcb99c841d366fe7e24b3e8a43c
4
- data.tar.gz: 5e0c70f36c6ca291a0e65e11137434474ad804829e67c553a7b8fbee651b5ea9
3
+ metadata.gz: 7b32c36a1629b320052d174d39a6330439f726c44dd78ff98b7fdb20d517fe1a
4
+ data.tar.gz: 0bc0cade506ab4db2aada6776bcf860f4a01ae3db8b83e530fa79b5d91755a12
5
5
  SHA512:
6
- metadata.gz: a717d7b6103c5e1df8b1cb044303114c159cbc31cb47e6f0a33e9c7e7906a204c0fd3ab92507b9eb903979c603c5031e192a2f6bf392ee4d2636eea5f3f3c88c
7
- data.tar.gz: 75a350a5053a490aff9cfac0b556e70dad2d2e20bf4cafb4408640b6d5c5dd932ec2264bf2cf952a3dec511b4e71855d4c5996e7acb32ccf6ea201b17943c80f
6
+ metadata.gz: 1cb159a3d41d2b09bd2880023df2beeb2af8c3fd82d702f6abb8e1cdcfe77833a7ac52e067e04f913ff304d3c6f0ab302810534ab98da67f396ccae4af1845cb
7
+ data.tar.gz: f917dbae1725dd89b83ddc8e8139e104660509e3bc978870b483441c824912b244ec474895b8b1a05edc95c726c1631ee4b1d4b01455bff410bc5f07c6d4b6cb
data/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AGENTS.md — MixinBot
2
2
 
3
- Ruby gem (v2.0.0): Mixin Network REST SDK + `mixinbot` CLI. Parity target: [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client).
3
+ Ruby gem (v2.1.0): Mixin Network REST SDK + `mixinbot` CLI. Parity targets: [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client), [bot-api-nodejs-client](https://github.com/MixinNetwork/bot-api-nodejs-client).
4
4
 
5
5
  ## Commands
6
6
 
@@ -35,7 +35,7 @@ docs/agent/ # LLM-oriented CLI and cookbook docs
35
35
  ## CI and release
36
36
 
37
37
  - **CI** (`.github/workflows/ci.yml`): `pull_request` and `push` to `main` — `rake test` on Ruby 3.2/3.3/4.0, `rake rubocop` (3.3), `rake mixin_bot:api_coverage`.
38
- - **Release** (`.github/workflows/release.yml`): push tag `v*` (must match `MixinBot::VERSION`, e.g. tag `v2.0.0` for `VERSION = '2.0.0'`) → `rake build` → RubyGems via [trusted publishing](https://guides.rubygems.org/trusted-publishing/) (OIDC; workflow `release.yml`, no repo secret).
38
+ - **Release** (`.github/workflows/release.yml`): push tag `v*` (must match `MixinBot::VERSION`, e.g. tag `v2.1.0` for `VERSION = '2.1.0'`) → `rake build` → RubyGems via [trusted publishing](https://guides.rubygems.org/trusted-publishing/) (OIDC; workflow `release.yml`, no repo secret) → GitHub Release (notes from `CHANGELOG.md`, `.gem` attached).
39
39
  - **Dependabot** (`.github/dependabot.yml`): weekly Bundler and GitHub Actions updates; Dependabot PRs use the same CI workflow.
40
40
 
41
41
  ## Conventions
data/API_COVERAGE.md CHANGED
@@ -1,8 +1,10 @@
1
- # Mixin Go SDK API Coverage
1
+ # Mixin SDK API Coverage
2
2
 
3
- Reference: [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client) (`package bot`).
3
+ Go reference: [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client) (`package bot`).
4
4
 
5
- Status values: `done` | `alias` | `n/a` (CLI-only / config)
5
+ Node reference: [bot-api-nodejs-client](https://github.com/MixinNetwork/bot-api-nodejs-client) (`@mixin.dev/mixin-node-sdk`).
6
+
7
+ Status values: `done` | `alias` | `n/a` (CLI-only / config / platform-specific)
6
8
 
7
9
  | Go symbol | Ruby method | HTTP / notes | Status |
8
10
  |-----------|-------------|--------------|--------|
@@ -140,4 +142,79 @@ Status values: `done` | `alias` | `n/a` (CLI-only / config)
140
142
  | NewSafeUser | `MixinBot::Configuration` | config | n/a |
141
143
  | cli/*, examples/*, mixin/rpc main | `mixinbot call` / `mixinbot list` | CLI dispatch to `MixinBot::API` | done |
142
144
 
145
+ ## Node SDK
146
+
147
+ TS-only or Node-first REST surfaces. Ruby methods follow snake_case; aliases mirror TS names where helpful.
148
+
149
+ | TS symbol | Ruby method | HTTP / notes | Status |
150
+ |-----------|-------------|--------------|--------|
151
+ | **Circle** |
152
+ | circle.fetch | `API#circle` | GET `/circles/:id` | done |
153
+ | circle.fetchList | `API#circles` | GET `/circles` | done |
154
+ | circle.conversations | `API#circle_conversations` | GET `/circles/:id/conversations` | done |
155
+ | circle.create | `API#create_circle` | POST `/circles` | done |
156
+ | circle.update | `API#update_circle` | POST `/circles/:id` | done |
157
+ | circle.delete | `API#delete_circle` | POST `/circles/:id/delete` | done |
158
+ | circle.addUser | `API#add_user_to_circle` | POST `/users/:id/circles` | done |
159
+ | circle.removeUser | `API#remove_user_from_circle` | POST `/users/:id/circles` | done |
160
+ | circle.addConversation | `API#add_conversation_to_circle` | POST `/conversations/:id/circles` | done |
161
+ | circle.removeConversation | `API#remove_conversation_from_circle` | POST `/conversations/:id/circles` | done |
162
+ | **App** |
163
+ | app.fetch | `API#app` | GET `/apps/:id` | done |
164
+ | app.fetchList | `API#apps` | GET `/apps` | done |
165
+ | app.properties | `API#app_properties` | GET `/apps/property` | done |
166
+ | app.billing | `API#app_billing` | GET `/safe/apps/:id/billing` | done |
167
+ | app.create | `API#create_app` | POST `/apps` | done |
168
+ | app.update | `API#update_app` | POST `/apps/:id` | done |
169
+ | app.updateSecret | `API#rotate_app_secret` | POST `/apps/:id/secret` | done |
170
+ | app.updateSafeSession | `API#update_app_safe_session` | POST `/safe/apps/:id/session` | done |
171
+ | app.registerSafe | `API#register_app_safe` | POST `/safe/apps/:id/register` | done |
172
+ | app.favorite / unfavorite | `API#add_favorite_app` / `#remove_favorite_app` | POST `/apps/:id/favorite` | done |
173
+ | app.favorites | `API#favorite_apps` | GET `/users/:id/apps/favorite` | done |
174
+ | app.migrate | `API#transfer_app_ownership` | POST `/apps/:id/transfer` | done |
175
+ | **OAuth** |
176
+ | oauth.getToken | `API#oauth_token` | POST `/oauth/token` | done |
177
+ | oauth.authorize | `API#authorize_code` | POST `/oauth/authorize` | done |
178
+ | oauth.authorizations | `API#authorizations` | GET `/authorizations` | done |
179
+ | oauth.revokeAuthorize | `API#revoke_authorization` | POST `/oauth/cancel` | done |
180
+ | **User** |
181
+ | user.profile | `API#me` | GET `/me` | done |
182
+ | user.friends | `API#friends` | GET `/friends` | done |
183
+ | user.blockings | `API#blocking_users` | GET `/blocking_users` | done |
184
+ | user.rotateCode | `API#rotate_user_code` | GET `/me/code` | done |
185
+ | user.search | `API#search_user` | GET `/search/:q` | done |
186
+ | user.fetch | `API#user` | GET `/users/:id` | done |
187
+ | user.fetchList | `API#fetch_users` | POST `/users/fetch` | done |
188
+ | user.createBareUser | `API#create_user` | POST `/users` | done |
189
+ | user.update | `API#update_me` | POST `/me` | done |
190
+ | user.updatePreferences | `API#update_preferences` | POST `/me/preferences` | done |
191
+ | user.updateRelationships | `API#relationship` | POST `/relationships` | done |
192
+ | user.logs | `API#user_logs` | GET `/logs` | done |
193
+ | **Conversation** |
194
+ | conversation.mute / unmute | `API#mute_conversation` / `#unmute_conversation` | POST `/conversations/:id/mute` | done |
195
+ | conversation.disappearDuration | `API#set_conversation_disappear_duration` | POST `/conversations/:id/disappear` | done |
196
+ | conversation.updateGroupInfo | `API#update_conversation` | POST `/conversations/:id` | done |
197
+ | conversation.* (CRUD/participants) | `API#conversation`, `#create_*`, `#join_*`, etc. | various | done |
198
+ | **Message** |
199
+ | message.sendAcknowledgement(s) | `API#acknowledge_message` / `#acknowledge_messages` | POST `/acknowledgements` | done |
200
+ | message.sendSticker/Audio/Video/Live/Location/Transfer | `API#send_*_message` | POST `/messages` | done |
201
+ | message.sendText/Image/File/Post/Contact/AppCard/AppButton/Recall | `API#send_*_message` | POST `/messages` | done |
202
+ | **Code** |
203
+ | code.fetch | `API#read_code` | GET `/codes/:id` | done |
204
+ | code.schemes | `API#create_scheme` | POST `/schemes` | done |
205
+ | **Address** |
206
+ | address.fetchListOfChain | `API#safe_withdraw_addresses` | GET `/safe/addresses?chain=` | done |
207
+ | address.fetch/create/delete | `API#get_withdraw_address`, `#create_withdraw_address`, `#delete_withdraw_address` | `/addresses` | done |
208
+ | **External** |
209
+ | external.proxy | `API#external_proxy` | POST `/external/proxy` | done |
210
+ | external.deposits | `API#transactions` (legacy) | GET `/external/transactions` | done |
211
+ | external.checkAddress | `API#check_address` | GET `/external/addresses/check` | done |
212
+ | external.exchangeRates | `API#fiats` | GET `/external/fiats` | done |
213
+ | **Safe / UTXO / Transfer / Network / etc.** |
214
+ | safe.* / utxo.* / transfer.* / network.* | spread across existing `API` modules | same HTTP paths as TS | done |
215
+ | **Blaze** |
216
+ | blaze.loop | `API#blaze` | WebSocket | done |
217
+ | **WebView** |
218
+ | WebViewApi | — | browser bridge | n/a |
219
+
143
220
  Update this file when adding or changing API surfaces. Run `rake mixin_bot:api_coverage` to ensure no `missing` rows remain.
data/CHANGELOG.md CHANGED
@@ -7,26 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Added
10
+ ## [2.1.0] - 2026-05-24
11
11
 
12
- - **`mixinbot call METHOD`** and **`mixinbot list`** — invoke any public `MixinBot::API` method from the CLI with JSON keyword arguments (`-d`).
13
- - **`mixinbot utils call`** / **`mixinbot utils list`** — same for `MixinBot.utils` helpers.
12
+ ### Added
14
13
 
15
- ### Changed
14
+ - **Node SDK REST parity** with [bot-api-nodejs-client](https://github.com/MixinNetwork/bot-api-nodejs-client): Circle API (`API::Circle`), `external_proxy`, extended App CRUD/Safe registration, OAuth `authorizations` / `revoke_authorization`, user `blocking_users` / `rotate_user_code` / `user_logs`, conversation mute/disappear, HTTP message acknowledgements and additional send helpers, `create_scheme`, `safe_withdraw_addresses`, and query params on `pending_safe_deposits`.
15
+ - **API_COVERAGE.md** Node SDK section mapping TS symbols to Ruby methods.
16
16
 
17
- - **`mixinbot transfer`** — uses Safe API (`create_safe_transfer`) instead of legacy `POST /transfers`.
18
- - **`mixinbot api`** — routes through `MixinBot::Client` (supports JSON array POST bodies); keystore loading includes `spend_key` and `client_secret`.
19
- - **`mixinbot updatetip`** — uses `update_tip_pin` instead of misusing `update_pin`.
20
- - **`mixinbot safetransfer`** — delegates to `transfer` (no duplicated signing pipeline).
17
+ ## [2.0.1] - 2026-05-24
21
18
 
22
- ### Deprecated
19
+ ### Fixed
23
20
 
24
- - **`mixinbot legacy-transfer`** — explicit legacy transfer command (replaces old default `transfer` behavior).
25
- - **`mixinbot safetransfer`** — use `transfer` instead.
21
+ - **`StringIO.new`** — use keyword `contents:` for Ruby 4 compatibility (`lib/mixin_bot/api/message.rb`).
26
22
 
27
- ### Fixed
23
+ ### Changed
28
24
 
29
- - **`mixinbot nftmemo`** calls `MixinBot.utils.nft_memo` (was a broken `nft` alias).
25
+ - Release workflow creates a GitHub Release with notes from `CHANGELOG.md` when publishing version tags.
30
26
 
31
27
  ## [2.0.0] - 2026-05-16
32
28
 
data/README.md CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  Ruby SDK and CLI for [Mixin Network](https://developers.mixin.one/docs): authenticated REST calls, **Safe** UTXO transfers, Blaze messaging, network asset catalog, inscriptions, invoices and mix addresses, transaction encoding, and optional **MVM** (Mixin Virtual Machine) helpers.
6
6
 
7
- The gem aims for **parity with the official [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client)** Go SDK. See [API_COVERAGE.md](API_COVERAGE.md) for the full mapping; run `rake mixin_bot:api_coverage` to confirm no gaps are marked missing.
7
+ The gem aims for **parity with the official [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client)** Go SDK and **[bot-api-nodejs-client](https://github.com/MixinNetwork/bot-api-nodejs-client)** Node SDK. See [API_COVERAGE.md](API_COVERAGE.md) for the full mapping; run `rake mixin_bot:api_coverage` to confirm no gaps are marked missing.
8
8
 
9
- Current gem version: **2.0.0** (see [CHANGELOG.md](CHANGELOG.md) for breaking changes and deprecations).
9
+ Current gem version: **2.1.0** (see [CHANGELOG.md](CHANGELOG.md) for breaking changes and deprecations).
10
10
 
11
11
  ## Requirements
12
12
 
@@ -353,14 +353,14 @@ Publishing to [RubyGems.org](https://rubygems.org/gems/mixin_bot) is automated w
353
353
 
354
354
  1. Bump `MixinBot::VERSION` in `lib/mixin_bot/version.rb` and update `CHANGELOG.md`.
355
355
  2. Commit and push to `main`.
356
- 3. Create and push a tag matching the gem version (e.g. `v2.0.1` for version `2.0.1`):
356
+ 3. Create and push a tag matching the gem version (e.g. `v2.1.0` for version `2.1.0`):
357
357
 
358
358
  ```bash
359
- git tag v2.0.1
360
- git push origin v2.0.1
359
+ git tag v2.1.0
360
+ git push origin v2.1.0
361
361
  ```
362
362
 
363
- The [Release workflow](.github/workflows/release.yml) builds the gem and publishes to RubyGems.org via [trusted publishing](https://guides.rubygems.org/trusted-publishing/) (GitHub OIDC; trusted publisher for workflow `release.yml` on `an-lee/mixin_bot`). To build without publishing, run the Release workflow manually with **dry run** enabled.
363
+ The [Release workflow](.github/workflows/release.yml) builds the gem, publishes to RubyGems.org via [trusted publishing](https://guides.rubygems.org/trusted-publishing/) (GitHub OIDC; trusted publisher for workflow `release.yml` on `an-lee/mixin_bot`), and creates a GitHub Release with notes from `CHANGELOG.md` and the `.gem` attached. To build without publishing, run the Release workflow manually with **dry run** enabled.
364
364
 
365
365
  ## References
366
366
 
@@ -3,17 +3,85 @@
3
3
  module MixinBot
4
4
  class API
5
5
  module App
6
+ def app(app_id, access_token: nil)
7
+ path = format('/apps/%<id>s', id: app_id)
8
+ client.get path, access_token:
9
+ end
10
+ alias fetch_app app
11
+
12
+ def apps(access_token: nil)
13
+ client.get '/apps', access_token:
14
+ end
15
+ alias fetch_apps apps
16
+
17
+ def app_properties(access_token: nil)
18
+ client.get '/apps/property', access_token:
19
+ end
20
+ alias app_property app_properties
21
+
22
+ def app_billing(app_id, access_token: nil)
23
+ path = format('/safe/apps/%<id>s/billing', id: app_id)
24
+ client.get path, access_token:
25
+ end
26
+
27
+ def create_app(**kwargs)
28
+ payload = {
29
+ redirect_uri: kwargs[:redirect_uri],
30
+ home_uri: kwargs[:home_uri],
31
+ name: kwargs[:name],
32
+ description: kwargs[:description],
33
+ icon_base64: kwargs[:icon_base64],
34
+ category: kwargs[:category],
35
+ capabilities: kwargs[:capabilities],
36
+ resource_patterns: kwargs[:resource_patterns]
37
+ }.compact
38
+ client.post '/apps', **payload, access_token: kwargs[:access_token]
39
+ end
40
+
41
+ def update_app(app_id, **kwargs)
42
+ path = format('/apps/%<id>s', id: app_id)
43
+ payload = {
44
+ redirect_uri: kwargs[:redirect_uri],
45
+ home_uri: kwargs[:home_uri],
46
+ name: kwargs[:name],
47
+ description: kwargs[:description],
48
+ icon_base64: kwargs[:icon_base64],
49
+ category: kwargs[:category],
50
+ capabilities: kwargs[:capabilities],
51
+ resource_patterns: kwargs[:resource_patterns]
52
+ }.compact
53
+ client.post path, **payload, access_token: kwargs[:access_token]
54
+ end
55
+
56
+ def rotate_app_secret(app_id, access_token: nil)
57
+ path = format('/apps/%<id>s/secret', id: app_id)
58
+ client.post path, access_token:
59
+ end
60
+ alias update_app_secret rotate_app_secret
61
+
62
+ def update_app_safe_session(app_id, session_public_key:, access_token: nil)
63
+ path = format('/safe/apps/%<id>s/session', id: app_id)
64
+ client.post path, session_public_key:, access_token:
65
+ end
66
+
67
+ def register_app_safe(app_id, spend_public_key:, signature_base64:, access_token: nil)
68
+ path = format('/safe/apps/%<id>s/register', id: app_id)
69
+ client.post path, spend_public_key:, signature_base64:, access_token:
70
+ end
71
+
6
72
  def add_favorite_app(app_id, access_token: nil)
7
73
  path = format('/apps/%<id>s/favorite', id: app_id)
8
74
 
9
75
  client.post path, access_token:
10
76
  end
77
+ alias favorite_app add_favorite_app
11
78
 
12
79
  def remove_favorite_app(app_id, access_token: nil)
13
80
  path = format('/apps/%<id>s/unfavorite', id: app_id)
14
81
 
15
82
  client.post path, access_token:
16
83
  end
84
+ alias unfavorite_app remove_favorite_app
17
85
 
18
86
  def favorite_apps(user_id = nil, access_token: nil)
19
87
  path = format('/users/%<id>s/apps/favorite', id: user_id || config.app_id)
@@ -56,6 +56,17 @@ module MixinBot
56
56
  client.post path, **payload, access_token: kwargs[:access_token]
57
57
  end
58
58
 
59
+ def authorizations(app_id: nil, access_token: nil)
60
+ params = {}
61
+ params[:app] = app_id if app_id
62
+ client.get '/authorizations', **params, access_token:
63
+ end
64
+
65
+ def revoke_authorization(client_id, access_token: nil)
66
+ client.post '/oauth/cancel', client_id:, access_token:
67
+ end
68
+ alias revoke_authorize revoke_authorization
69
+
59
70
  def authorization_data(app_id, scope = ['PROFILE:READ'])
60
71
  @_app_id = app_id
61
72
  @_scope = scope.join(' ')
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MixinBot
4
+ class API
5
+ module Circle
6
+ def circle(circle_id, access_token: nil)
7
+ path = format('/circles/%<circle_id>s', circle_id:)
8
+ client.get path, access_token:
9
+ end
10
+ alias fetch_circle circle
11
+
12
+ def circles(access_token: nil)
13
+ client.get '/circles', access_token:
14
+ end
15
+ alias fetch_circles circles
16
+
17
+ def circle_conversations(circle_id, **params)
18
+ path = format('/circles/%<circle_id>s/conversations', circle_id:)
19
+ client.get path, **params.compact, access_token: params[:access_token]
20
+ end
21
+
22
+ def create_circle(name:, access_token: nil)
23
+ client.post '/circles', name:, access_token:
24
+ end
25
+
26
+ def update_circle(circle_id, name:, access_token: nil)
27
+ path = format('/circles/%<circle_id>s', circle_id:)
28
+ client.post path, name:, access_token:
29
+ end
30
+
31
+ def delete_circle(circle_id, access_token: nil)
32
+ path = format('/circles/%<circle_id>s/delete', circle_id:)
33
+ client.post path, access_token:
34
+ end
35
+
36
+ def add_user_to_circle(user_id:, circle_id:, access_token: nil)
37
+ path = format('/users/%<user_id>s/circles', user_id:)
38
+ client.post path, circle_id:, action: 'ADD', access_token:
39
+ end
40
+
41
+ def remove_user_from_circle(user_id:, circle_id:, access_token: nil)
42
+ path = format('/users/%<user_id>s/circles', user_id:)
43
+ client.post path, circle_id:, action: 'REMOVE', access_token:
44
+ end
45
+
46
+ def add_conversation_to_circle(conversation_id:, circle_id:, access_token: nil)
47
+ path = format('/conversations/%<conversation_id>s/circles', conversation_id:)
48
+ client.post path, circle_id:, action: 'ADD', access_token:
49
+ end
50
+
51
+ def remove_conversation_from_circle(conversation_id:, circle_id:, access_token: nil)
52
+ path = format('/conversations/%<conversation_id>s/circles', conversation_id:)
53
+ client.post path, circle_id:, action: 'REMOVE', access_token:
54
+ end
55
+ end
56
+ end
57
+ end
@@ -11,6 +11,11 @@ module MixinBot
11
11
  def read_multisig_by_code(code_id, access_token: nil)
12
12
  read_code(code_id, access_token:)
13
13
  end
14
+
15
+ def create_scheme(target, access_token: nil)
16
+ client.post '/schemes', target:, access_token:
17
+ end
18
+ alias schemes create_scheme
14
19
  end
15
20
  end
16
21
  end
@@ -55,23 +55,40 @@ module MixinBot
55
55
  )
56
56
  end
57
57
 
58
- def update_group_conversation_name(name:, conversation_id:, access_token: nil)
58
+ def update_conversation(conversation_id:, **kwargs)
59
59
  path = format('/conversations/%<id>s', id: conversation_id)
60
60
  payload = {
61
- name:
62
- }
61
+ name: kwargs[:name],
62
+ announcement: kwargs[:announcement]
63
+ }.compact
64
+ client.post path, **payload, access_token: kwargs[:access_token]
65
+ end
66
+ alias update_group_info update_conversation
63
67
 
64
- client.post path, **payload, access_token:
68
+ def update_group_conversation_name(name:, conversation_id:, access_token: nil)
69
+ update_conversation(conversation_id:, name:, access_token:)
65
70
  end
66
71
 
67
72
  def update_group_conversation_announcement(announcement:, conversation_id:, access_token: nil)
68
- path = format('/conversations/%<id>s', id: conversation_id)
69
- payload = {
70
- announcement:
71
- }
73
+ update_conversation(conversation_id:, announcement:, access_token:)
74
+ end
75
+
76
+ def mute_conversation(conversation_id, duration:, access_token: nil)
77
+ path = format('/conversations/%<id>s/mute', id: conversation_id)
78
+ client.post path, duration:, access_token:
79
+ end
80
+ alias mute mute_conversation
81
+
82
+ def unmute_conversation(conversation_id, access_token: nil)
83
+ mute_conversation conversation_id, duration: 0, access_token:
84
+ end
85
+ alias unmute unmute_conversation
72
86
 
73
- client.post path, **payload, access_token:
87
+ def set_conversation_disappear_duration(conversation_id, duration:, access_token: nil)
88
+ path = format('/conversations/%<id>s/disappear', id: conversation_id)
89
+ client.post path, duration:, access_token:
74
90
  end
91
+ alias disappear_duration set_conversation_disappear_duration
75
92
 
76
93
  # participants = [{ user_id: "" }]
77
94
  def add_conversation_participants(conversation_id:, user_ids:, access_token: nil)
@@ -3,8 +3,15 @@
3
3
  module MixinBot
4
4
  class API
5
5
  module Deposit
6
- def pending_safe_deposits
7
- client.get '/safe/deposits', access_token: ''
6
+ def pending_safe_deposits(**params)
7
+ query = {
8
+ limit: params[:limit],
9
+ offset: params[:offset],
10
+ asset: params[:asset],
11
+ destination: params[:destination],
12
+ tag: params[:tag]
13
+ }.compact
14
+ client.get '/safe/deposits', **query, access_token: params[:access_token] || ''
8
15
  end
9
16
  alias fetch_pending_safe_deposits pending_safe_deposits
10
17
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MixinBot
4
+ class API
5
+ module External
6
+ def external_proxy(method:, params: [], access_token: nil)
7
+ client.post '/external/proxy', method:, params:, access_token:
8
+ end
9
+ alias proxy external_proxy
10
+ end
11
+ end
12
+ end
@@ -126,6 +126,27 @@ module MixinBot
126
126
  path = '/relationships'
127
127
  client.post path, user_id:, action:, access_token:
128
128
  end
129
+ alias update_relationship relationship
130
+
131
+ def blocking_users(access_token: nil)
132
+ client.get '/blocking_users', access_token:
133
+ end
134
+ alias blockings blocking_users
135
+
136
+ def rotate_user_code(access_token: nil)
137
+ client.get '/me/code', access_token:
138
+ end
139
+ alias rotate_code rotate_user_code
140
+
141
+ def user_logs(**params)
142
+ query = {
143
+ limit: params[:limit],
144
+ offset: params[:offset],
145
+ category: params[:category]
146
+ }.compact
147
+ client.get '/logs', **query, access_token: params[:access_token]
148
+ end
149
+ alias logs user_logs
129
150
  end
130
151
  end
131
152
  end
@@ -48,6 +48,18 @@ module MixinBot
48
48
  base_message_params(options.merge(category: 'PLAIN_VIDEO'))
49
49
  end
50
50
 
51
+ def plain_live(options)
52
+ base_message_params(options.merge(category: 'PLAIN_LIVE'))
53
+ end
54
+
55
+ def plain_location(options)
56
+ base_message_params(options.merge(category: 'PLAIN_LOCATION'))
57
+ end
58
+
59
+ def transfer_message(options)
60
+ base_message_params(options.merge(category: 'SYSTEM_ACCOUNT_SNAPSHOT'))
61
+ end
62
+
51
63
  def app_card(options)
52
64
  base_message_params(options.merge(category: 'APP_CARD'))
53
65
  end
@@ -105,7 +117,7 @@ module MixinBot
105
117
  params:
106
118
  }.to_json
107
119
 
108
- io = StringIO.new 'wb'
120
+ io = StringIO.new
109
121
  gzip = Zlib::GzipWriter.new io
110
122
  gzip.write msg
111
123
  gzip.close
@@ -141,6 +153,30 @@ module MixinBot
141
153
  send_message app_button_group(options)
142
154
  end
143
155
 
156
+ def send_sticker_message(options)
157
+ send_message plain_sticker(options)
158
+ end
159
+
160
+ def send_audio_message(options)
161
+ send_message plain_audio(options)
162
+ end
163
+
164
+ def send_video_message(options)
165
+ send_message plain_video(options)
166
+ end
167
+
168
+ def send_live_message(options)
169
+ send_message plain_live(options)
170
+ end
171
+
172
+ def send_location_message(options)
173
+ send_message plain_location(options)
174
+ end
175
+
176
+ def send_transfer_message(options)
177
+ send_message transfer_message(options)
178
+ end
179
+
144
180
  def recall_message(message_id, options)
145
181
  send_message [recall_message_params(message_id, options)]
146
182
  end
@@ -149,6 +185,17 @@ module MixinBot
149
185
  send_message messages
150
186
  end
151
187
 
188
+ def acknowledge_message(message_id, status: 'READ', access_token: nil)
189
+ payload = { message_id:, status: }
190
+ client.post '/acknowledgements', payload, access_token:
191
+ end
192
+ alias send_acknowledgement acknowledge_message
193
+
194
+ def acknowledge_messages(messages, access_token: nil)
195
+ client.post '/acknowledgements', *messages, access_token:
196
+ end
197
+ alias send_acknowledgements acknowledge_messages
198
+
152
199
  # http post request
153
200
  def send_message(payload)
154
201
  path = '/messages'
@@ -70,6 +70,11 @@ module MixinBot
70
70
  end
71
71
  alias get_addresses_by_asset_id withdraw_addresses
72
72
 
73
+ def safe_withdraw_addresses(chain_id, access_token: nil)
74
+ client.get '/safe/addresses', chain: chain_id, access_token:
75
+ end
76
+ alias fetch_list_of_chain safe_withdraw_addresses
77
+
73
78
  def check_address(asset:, destination:, tag: nil)
74
79
  client.get '/external/addresses/check', asset:, destination:, tag:, access_token: ''
75
80
  end
data/lib/mixin_bot/api.rb CHANGED
@@ -10,10 +10,12 @@ require_relative 'api/auth'
10
10
  require_relative 'api/blaze'
11
11
  require_relative 'api/chain'
12
12
  require_relative 'api/code'
13
+ require_relative 'api/circle'
13
14
  require_relative 'api/computer_api'
14
15
  require_relative 'api/conversation'
15
16
  require_relative 'api/deposit'
16
17
  require_relative 'api/encrypted_message'
18
+ require_relative 'api/external'
17
19
  require_relative 'api/fiat'
18
20
  require_relative 'api/inscription'
19
21
  require_relative 'api/legacy_collectible'
@@ -338,10 +340,12 @@ module MixinBot
338
340
  include MixinBot::API::Blaze
339
341
  include MixinBot::API::Chain
340
342
  include MixinBot::API::Code
343
+ include MixinBot::API::Circle
341
344
  include MixinBot::API::ComputerApi
342
345
  include MixinBot::API::Conversation
343
346
  include MixinBot::API::Deposit
344
347
  include MixinBot::API::EncryptedMessage
348
+ include MixinBot::API::External
345
349
  include MixinBot::API::Fiat
346
350
  include MixinBot::API::Inscription
347
351
  include MixinBot::API::LegacyCollectible
@@ -11,5 +11,5 @@ module MixinBot
11
11
  #
12
12
  # @see https://semver.org/
13
13
  #
14
- VERSION = '2.0.0'
14
+ VERSION = '2.1.0'
15
15
  end
data/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # MixinBot
2
2
 
3
- > Ruby SDK and CLI for Mixin Network: Safe UTXO transfers, REST API, Blaze messaging, transaction crypto, optional MVM helpers. Ruby >= 3.2. Gem version 2.0.0.
3
+ > Ruby SDK and CLI for Mixin Network: Safe UTXO transfers, REST API, Blaze messaging, transaction crypto, optional MVM helpers. Ruby >= 3.2. Gem version 2.1.0.
4
4
 
5
5
  Important notes:
6
6
 
@@ -11,7 +11,7 @@ Important notes:
11
11
  ## Docs
12
12
 
13
13
  - [README](README.md): Install, config, API overview, CLI summary
14
- - [API coverage vs Go SDK](API_COVERAGE.md): Method parity matrix
14
+ - [API coverage vs Go/Node SDKs](API_COVERAGE.md): Method parity matrix
15
15
  - [CLI for agents](docs/agent/cli.md): Structured output, schema, examples
16
16
  - [Agent cookbook](docs/agent/cookbook.md): Common tasks (auth, transfer, messaging)
17
17
  - [Changelog](CHANGELOG.md): Breaking changes
@@ -25,5 +25,6 @@ Important notes:
25
25
  ## Optional
26
26
 
27
27
  - [Mixin official docs](https://developers.mixin.one/docs): External API reference
28
- - [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client): Parity reference
28
+ - [bot-api-go-client](https://github.com/MixinNetwork/bot-api-go-client): Go parity reference
29
+ - [bot-api-nodejs-client](https://github.com/MixinNetwork/bot-api-nodejs-client): Node parity reference
29
30
  - [Generated RDoc](doc/index.html): Full API reference (local)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixin_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - an-lee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-20 00:00:00.000000000 Z
11
+ date: 2026-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -282,11 +282,13 @@ files:
282
282
  - lib/mixin_bot/api/auth.rb
283
283
  - lib/mixin_bot/api/blaze.rb
284
284
  - lib/mixin_bot/api/chain.rb
285
+ - lib/mixin_bot/api/circle.rb
285
286
  - lib/mixin_bot/api/code.rb
286
287
  - lib/mixin_bot/api/computer_api.rb
287
288
  - lib/mixin_bot/api/conversation.rb
288
289
  - lib/mixin_bot/api/deposit.rb
289
290
  - lib/mixin_bot/api/encrypted_message.rb
291
+ - lib/mixin_bot/api/external.rb
290
292
  - lib/mixin_bot/api/fiat.rb
291
293
  - lib/mixin_bot/api/inscription.rb
292
294
  - lib/mixin_bot/api/legacy_collectible.rb