@1claw/openapi-spec 0.61.17 → 0.61.19

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.
Files changed (3) hide show
  1. package/openapi.json +981 -1
  2. package/openapi.yaml +591 -1
  3. package/package.json +1 -1
package/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "1Claw API",
5
- "version": "0.61.17",
5
+ "version": "0.61.19",
6
6
  "description": "Secure secret management for AI agents. Provides vaults, secrets,\npolicy-based access control, agent identity, Intents API,\nsharing, billing, and audit logging. Automations (workflow_spec,\nwebhook tokens, event triggers, Assist), cloud runtimes with\ninteractive shell sessions, agent memory, and discovery.\n\n## Domains\n\n`api.1claw.co` is canonical: it is the OIDC issuer, the `aud` the API\nmints, and the first entry in `servers` — a generated client takes its\nbase URL from there, and the previous ordering pointed every SDK at the\ndomain the issuer had already left. `api.1claw.xyz` still answers and is\nstill accepted on token validation, because tokens minted before the\nmove carry it; it is never minted now.\n\nOne deliberate exception: the Shroud attestation identity token is\nrequested from GCP with `audience: https://api.1claw.xyz`, so\n`/v1/shroud/attestation` reports that as its `expected_audience`. That\nis accurate rather than stale — the audience is a verification contract\nwith anyone already checking the token, and moving it is a breaking\nchange for them, not a rename.\n\nAll endpoints require JWT Bearer authentication unless marked with\n`security: []`.\n",
7
7
  "contact": {
8
8
  "email": "ops@1claw.co"
@@ -99,6 +99,10 @@
99
99
  "name": "Treasury Wallets",
100
100
  "description": "Multi-chain wallet generation for human users (replaces CDP embedded wallets)"
101
101
  },
102
+ {
103
+ "name": "Key Custody",
104
+ "description": "Customer-held key shares for non-custodial (threshold) signing keys"
105
+ },
102
106
  {
103
107
  "name": "Admin",
104
108
  "description": "Platform administration"
@@ -1172,6 +1176,11 @@
1172
1176
  },
1173
1177
  "created_at": {
1174
1178
  "type": "string"
1179
+ },
1180
+ "prf_supported": {
1181
+ "type": "boolean",
1182
+ "nullable": true,
1183
+ "description": "`true` — can hold a wallet share (WebAuthn PRF).\n`false` — cannot. `null` — registered before this\nwas captured.\n"
1175
1184
  }
1176
1185
  }
1177
1186
  }
@@ -8413,6 +8422,847 @@
8413
8422
  }
8414
8423
  }
8415
8424
  },
8425
+ "/v1/keys/{key_id}/client-share": {
8426
+ "parameters": [
8427
+ {
8428
+ "name": "key_id",
8429
+ "in": "path",
8430
+ "required": true,
8431
+ "description": "A treasury wallet id or an agent signing key id owned by the caller's org",
8432
+ "schema": {
8433
+ "type": "string",
8434
+ "format": "uuid"
8435
+ }
8436
+ }
8437
+ ],
8438
+ "put": {
8439
+ "tags": [
8440
+ "Key Custody"
8441
+ ],
8442
+ "summary": "Store the customer's wrapped share of a threshold key",
8443
+ "description": "Stores ciphertext the vault cannot open: the customer's share of a\n2-party threshold signing key, wrapped in the browser under the\npasskey's WebAuthn PRF output (`passkey_prf`, one wrap per credential)\nor under a recovery code (`recovery_code`, one per key). The vault\nkeeps the blob and its salt and returns them only to the owning user.\nHuman users only; the passkey must have reported PRF support at\nregistration. Idempotent per (key, credential).\n",
8444
+ "operationId": "putClientKeyShare",
8445
+ "security": [
8446
+ {
8447
+ "BearerAuth": []
8448
+ }
8449
+ ],
8450
+ "requestBody": {
8451
+ "required": true,
8452
+ "content": {
8453
+ "application/json": {
8454
+ "schema": {
8455
+ "$ref": "#/components/schemas/PutClientShareRequest"
8456
+ }
8457
+ }
8458
+ }
8459
+ },
8460
+ "responses": {
8461
+ "201": {
8462
+ "description": "Share stored",
8463
+ "content": {
8464
+ "application/json": {
8465
+ "schema": {
8466
+ "$ref": "#/components/schemas/ClientShareResponse"
8467
+ }
8468
+ }
8469
+ }
8470
+ },
8471
+ "400": {
8472
+ "$ref": "#/components/responses/BadRequest"
8473
+ },
8474
+ "401": {
8475
+ "$ref": "#/components/responses/Unauthorized"
8476
+ },
8477
+ "403": {
8478
+ "$ref": "#/components/responses/Forbidden"
8479
+ },
8480
+ "404": {
8481
+ "$ref": "#/components/responses/NotFound"
8482
+ }
8483
+ }
8484
+ },
8485
+ "get": {
8486
+ "tags": [
8487
+ "Key Custody"
8488
+ ],
8489
+ "summary": "List the caller's wrapped shares for a key",
8490
+ "description": "Returns every wrap on file for this key, unopened, to the user who\nstored them. `custody` tells you whether the key is `server` (1claw\nholds the whole private key) or `client_tss` (threshold; neither party\ncan sign alone). Funding a `client_tss` wallet needs at least two wraps.\n",
8491
+ "operationId": "listClientKeyShares",
8492
+ "security": [
8493
+ {
8494
+ "BearerAuth": []
8495
+ }
8496
+ ],
8497
+ "responses": {
8498
+ "200": {
8499
+ "description": "Wraps on file",
8500
+ "content": {
8501
+ "application/json": {
8502
+ "schema": {
8503
+ "$ref": "#/components/schemas/ClientShareListResponse"
8504
+ }
8505
+ }
8506
+ }
8507
+ },
8508
+ "401": {
8509
+ "$ref": "#/components/responses/Unauthorized"
8510
+ },
8511
+ "403": {
8512
+ "$ref": "#/components/responses/Forbidden"
8513
+ },
8514
+ "404": {
8515
+ "$ref": "#/components/responses/NotFound"
8516
+ }
8517
+ }
8518
+ }
8519
+ },
8520
+ "/v1/keys/{key_id}/client-share/rewrap": {
8521
+ "parameters": [
8522
+ {
8523
+ "name": "key_id",
8524
+ "in": "path",
8525
+ "required": true,
8526
+ "schema": {
8527
+ "type": "string",
8528
+ "format": "uuid"
8529
+ }
8530
+ }
8531
+ ],
8532
+ "post": {
8533
+ "tags": [
8534
+ "Key Custody"
8535
+ ],
8536
+ "summary": "Add a wrap for another credential or the recovery code",
8537
+ "description": "Same write as `PUT …/client-share`, for a key that already has at\nleast one wrap: the browser, holding the share in memory during a\npasskey session, re-wraps it under a newly added passkey's PRF\noutput or under the recovery code. 409 if no wrap exists yet.\n",
8538
+ "operationId": "rewrapClientKeyShare",
8539
+ "security": [
8540
+ {
8541
+ "BearerAuth": []
8542
+ }
8543
+ ],
8544
+ "requestBody": {
8545
+ "required": true,
8546
+ "content": {
8547
+ "application/json": {
8548
+ "schema": {
8549
+ "$ref": "#/components/schemas/PutClientShareRequest"
8550
+ }
8551
+ }
8552
+ }
8553
+ },
8554
+ "responses": {
8555
+ "201": {
8556
+ "description": "Wrap added",
8557
+ "content": {
8558
+ "application/json": {
8559
+ "schema": {
8560
+ "$ref": "#/components/schemas/ClientShareResponse"
8561
+ }
8562
+ }
8563
+ }
8564
+ },
8565
+ "400": {
8566
+ "$ref": "#/components/responses/BadRequest"
8567
+ },
8568
+ "401": {
8569
+ "$ref": "#/components/responses/Unauthorized"
8570
+ },
8571
+ "403": {
8572
+ "$ref": "#/components/responses/Forbidden"
8573
+ },
8574
+ "404": {
8575
+ "$ref": "#/components/responses/NotFound"
8576
+ },
8577
+ "409": {
8578
+ "$ref": "#/components/responses/Conflict"
8579
+ }
8580
+ }
8581
+ }
8582
+ },
8583
+ "/v1/keys/{key_id}/client-share/{share_id}": {
8584
+ "parameters": [
8585
+ {
8586
+ "name": "key_id",
8587
+ "in": "path",
8588
+ "required": true,
8589
+ "schema": {
8590
+ "type": "string",
8591
+ "format": "uuid"
8592
+ }
8593
+ },
8594
+ {
8595
+ "name": "share_id",
8596
+ "in": "path",
8597
+ "required": true,
8598
+ "schema": {
8599
+ "type": "string",
8600
+ "format": "uuid"
8601
+ }
8602
+ }
8603
+ ],
8604
+ "delete": {
8605
+ "tags": [
8606
+ "Key Custody"
8607
+ ],
8608
+ "summary": "Remove one wrap",
8609
+ "description": "Deletes a single wrap. Wraps tied to a passkey are also removed when\nthat passkey is deleted. Removing the last wrap of a `client_tss` key\nmakes the key unrecoverable — the vault holds only its own share.\n",
8610
+ "operationId": "deleteClientKeyShare",
8611
+ "security": [
8612
+ {
8613
+ "BearerAuth": []
8614
+ }
8615
+ ],
8616
+ "responses": {
8617
+ "204": {
8618
+ "description": "Wrap removed"
8619
+ },
8620
+ "401": {
8621
+ "$ref": "#/components/responses/Unauthorized"
8622
+ },
8623
+ "403": {
8624
+ "$ref": "#/components/responses/Forbidden"
8625
+ },
8626
+ "404": {
8627
+ "$ref": "#/components/responses/NotFound"
8628
+ }
8629
+ }
8630
+ }
8631
+ },
8632
+ "/v1/keys/tss/keygen/begin": {
8633
+ "post": {
8634
+ "tags": [
8635
+ "Key Custody"
8636
+ ],
8637
+ "summary": "Start a 2-party threshold key generation",
8638
+ "description": "Begins a distributed key generation between the vault (party 1) and the\ncaller's browser (party 2, `@1claw/tss-wasm`). The result is a\n`custody: client_tss` treasury wallet whose private key never exists\nanywhere: the vault keeps one FROST share, the caller keeps the other,\nwrapped under their passkey's PRF output. Requires a passkey with\n`prf_supported: true` and no active wallet on the chain. Chains: `solana`\n(Ed25519). Sessions expire after 10 minutes.\n",
8639
+ "operationId": "tssKeygenBegin",
8640
+ "security": [
8641
+ {
8642
+ "BearerAuth": []
8643
+ }
8644
+ ],
8645
+ "requestBody": {
8646
+ "required": true,
8647
+ "content": {
8648
+ "application/json": {
8649
+ "schema": {
8650
+ "type": "object",
8651
+ "required": [
8652
+ "chain"
8653
+ ],
8654
+ "properties": {
8655
+ "chain": {
8656
+ "type": "string",
8657
+ "enum": [
8658
+ "solana"
8659
+ ]
8660
+ }
8661
+ }
8662
+ }
8663
+ }
8664
+ }
8665
+ },
8666
+ "responses": {
8667
+ "201": {
8668
+ "description": "Session opened; the vault's round-1 package",
8669
+ "content": {
8670
+ "application/json": {
8671
+ "schema": {
8672
+ "type": "object",
8673
+ "properties": {
8674
+ "session_id": {
8675
+ "type": "string",
8676
+ "format": "uuid"
8677
+ },
8678
+ "chain": {
8679
+ "type": "string"
8680
+ },
8681
+ "curve": {
8682
+ "type": "string"
8683
+ },
8684
+ "server_identifier": {
8685
+ "type": "integer",
8686
+ "example": 1
8687
+ },
8688
+ "client_identifier": {
8689
+ "type": "integer",
8690
+ "example": 2
8691
+ },
8692
+ "server_round1": {
8693
+ "type": "string",
8694
+ "description": "Base64 FROST DKG round-1 package."
8695
+ },
8696
+ "expires_at": {
8697
+ "type": "string",
8698
+ "format": "date-time"
8699
+ }
8700
+ }
8701
+ }
8702
+ }
8703
+ }
8704
+ },
8705
+ "400": {
8706
+ "$ref": "#/components/responses/BadRequest"
8707
+ },
8708
+ "401": {
8709
+ "$ref": "#/components/responses/Unauthorized"
8710
+ },
8711
+ "403": {
8712
+ "$ref": "#/components/responses/Forbidden"
8713
+ },
8714
+ "409": {
8715
+ "$ref": "#/components/responses/Conflict"
8716
+ }
8717
+ }
8718
+ }
8719
+ },
8720
+ "/v1/keys/tss/keygen/round2": {
8721
+ "post": {
8722
+ "tags": [
8723
+ "Key Custody"
8724
+ ],
8725
+ "summary": "Threshold key generation, round 2",
8726
+ "operationId": "tssKeygenRound2",
8727
+ "security": [
8728
+ {
8729
+ "BearerAuth": []
8730
+ }
8731
+ ],
8732
+ "requestBody": {
8733
+ "required": true,
8734
+ "content": {
8735
+ "application/json": {
8736
+ "schema": {
8737
+ "type": "object",
8738
+ "required": [
8739
+ "session_id",
8740
+ "client_round1"
8741
+ ],
8742
+ "properties": {
8743
+ "session_id": {
8744
+ "type": "string",
8745
+ "format": "uuid"
8746
+ },
8747
+ "client_round1": {
8748
+ "type": "string",
8749
+ "description": "Base64 FROST DKG round-1 package from the browser."
8750
+ }
8751
+ }
8752
+ }
8753
+ }
8754
+ }
8755
+ },
8756
+ "responses": {
8757
+ "200": {
8758
+ "description": "The vault's round-2 package, addressed to the caller",
8759
+ "content": {
8760
+ "application/json": {
8761
+ "schema": {
8762
+ "type": "object",
8763
+ "properties": {
8764
+ "session_id": {
8765
+ "type": "string",
8766
+ "format": "uuid"
8767
+ },
8768
+ "server_round2": {
8769
+ "type": "string"
8770
+ }
8771
+ }
8772
+ }
8773
+ }
8774
+ }
8775
+ },
8776
+ "400": {
8777
+ "$ref": "#/components/responses/BadRequest"
8778
+ },
8779
+ "401": {
8780
+ "$ref": "#/components/responses/Unauthorized"
8781
+ },
8782
+ "404": {
8783
+ "$ref": "#/components/responses/NotFound"
8784
+ },
8785
+ "409": {
8786
+ "$ref": "#/components/responses/Conflict"
8787
+ }
8788
+ }
8789
+ }
8790
+ },
8791
+ "/v1/keys/tss/keygen/complete": {
8792
+ "post": {
8793
+ "tags": [
8794
+ "Key Custody"
8795
+ ],
8796
+ "summary": "Threshold key generation, final round",
8797
+ "description": "Needs `X-Passkey-Token` from a tx-assert with `action: tss_keygen` and\n`tx_digest` = hex SHA-256 of the session id. Creates the `client_tss`\nwallet and returns its address. The browser derives the same public key\npackage from the packages it already holds; store your share with\n`PUT /v1/keys/{key_id}/client-share` next.\n",
8798
+ "operationId": "tssKeygenComplete",
8799
+ "security": [
8800
+ {
8801
+ "BearerAuth": []
8802
+ }
8803
+ ],
8804
+ "parameters": [
8805
+ {
8806
+ "name": "X-Passkey-Token",
8807
+ "in": "header",
8808
+ "required": true,
8809
+ "schema": {
8810
+ "type": "string"
8811
+ }
8812
+ }
8813
+ ],
8814
+ "requestBody": {
8815
+ "required": true,
8816
+ "content": {
8817
+ "application/json": {
8818
+ "schema": {
8819
+ "type": "object",
8820
+ "required": [
8821
+ "session_id",
8822
+ "client_round2"
8823
+ ],
8824
+ "properties": {
8825
+ "session_id": {
8826
+ "type": "string",
8827
+ "format": "uuid"
8828
+ },
8829
+ "client_round2": {
8830
+ "type": "string",
8831
+ "description": "Base64 FROST DKG round-2 package from the browser, addressed to the vault."
8832
+ }
8833
+ }
8834
+ }
8835
+ }
8836
+ }
8837
+ },
8838
+ "responses": {
8839
+ "201": {
8840
+ "description": "Wallet created",
8841
+ "content": {
8842
+ "application/json": {
8843
+ "schema": {
8844
+ "type": "object",
8845
+ "properties": {
8846
+ "key_id": {
8847
+ "type": "string",
8848
+ "format": "uuid"
8849
+ },
8850
+ "chain": {
8851
+ "type": "string"
8852
+ },
8853
+ "curve": {
8854
+ "type": "string"
8855
+ },
8856
+ "custody": {
8857
+ "type": "string",
8858
+ "enum": [
8859
+ "client_tss"
8860
+ ]
8861
+ },
8862
+ "address": {
8863
+ "type": "string"
8864
+ },
8865
+ "public_key_hex": {
8866
+ "type": "string"
8867
+ },
8868
+ "public_key_package": {
8869
+ "type": "string",
8870
+ "description": "Base64 FROST public key package."
8871
+ }
8872
+ }
8873
+ }
8874
+ }
8875
+ }
8876
+ },
8877
+ "400": {
8878
+ "$ref": "#/components/responses/BadRequest"
8879
+ },
8880
+ "401": {
8881
+ "$ref": "#/components/responses/Unauthorized"
8882
+ },
8883
+ "403": {
8884
+ "$ref": "#/components/responses/Forbidden"
8885
+ },
8886
+ "404": {
8887
+ "$ref": "#/components/responses/NotFound"
8888
+ },
8889
+ "409": {
8890
+ "$ref": "#/components/responses/Conflict"
8891
+ }
8892
+ }
8893
+ }
8894
+ },
8895
+ "/v1/keys/{key_id}/tss/sign/begin": {
8896
+ "parameters": [
8897
+ {
8898
+ "name": "key_id",
8899
+ "in": "path",
8900
+ "required": true,
8901
+ "schema": {
8902
+ "type": "string",
8903
+ "format": "uuid"
8904
+ }
8905
+ }
8906
+ ],
8907
+ "post": {
8908
+ "tags": [
8909
+ "Key Custody"
8910
+ ],
8911
+ "summary": "Threshold signing, round 1",
8912
+ "description": "Needs `X-Passkey-Token` from a tx-assert with `action: tss_sign` and\n`tx_digest` = hex SHA-256 of `message`. The message must be a decodable\nSolana transaction message; every transfer destination in it is checked\nagainst the OFAC SDN list before the vault commits. Returns the vault's\nsigning commitments; nonces are single-use and expire with the session.\n",
8913
+ "operationId": "tssSignBegin",
8914
+ "security": [
8915
+ {
8916
+ "BearerAuth": []
8917
+ }
8918
+ ],
8919
+ "parameters": [
8920
+ {
8921
+ "name": "X-Passkey-Token",
8922
+ "in": "header",
8923
+ "required": true,
8924
+ "schema": {
8925
+ "type": "string"
8926
+ }
8927
+ }
8928
+ ],
8929
+ "requestBody": {
8930
+ "required": true,
8931
+ "content": {
8932
+ "application/json": {
8933
+ "schema": {
8934
+ "type": "object",
8935
+ "required": [
8936
+ "message"
8937
+ ],
8938
+ "properties": {
8939
+ "message": {
8940
+ "type": "string",
8941
+ "description": "Base64 bytes to sign (the serialised transaction message)."
8942
+ }
8943
+ }
8944
+ }
8945
+ }
8946
+ }
8947
+ },
8948
+ "responses": {
8949
+ "201": {
8950
+ "description": "Session opened",
8951
+ "content": {
8952
+ "application/json": {
8953
+ "schema": {
8954
+ "type": "object",
8955
+ "properties": {
8956
+ "session_id": {
8957
+ "type": "string",
8958
+ "format": "uuid"
8959
+ },
8960
+ "key_id": {
8961
+ "type": "string",
8962
+ "format": "uuid"
8963
+ },
8964
+ "message_digest": {
8965
+ "type": "string"
8966
+ },
8967
+ "server_commitments": {
8968
+ "type": "string"
8969
+ },
8970
+ "expires_at": {
8971
+ "type": "string",
8972
+ "format": "date-time"
8973
+ }
8974
+ }
8975
+ }
8976
+ }
8977
+ }
8978
+ },
8979
+ "400": {
8980
+ "$ref": "#/components/responses/BadRequest"
8981
+ },
8982
+ "401": {
8983
+ "$ref": "#/components/responses/Unauthorized"
8984
+ },
8985
+ "403": {
8986
+ "$ref": "#/components/responses/Forbidden"
8987
+ },
8988
+ "404": {
8989
+ "$ref": "#/components/responses/NotFound"
8990
+ }
8991
+ }
8992
+ }
8993
+ },
8994
+ "/v1/keys/{key_id}/tss/sign/complete": {
8995
+ "parameters": [
8996
+ {
8997
+ "name": "key_id",
8998
+ "in": "path",
8999
+ "required": true,
9000
+ "schema": {
9001
+ "type": "string",
9002
+ "format": "uuid"
9003
+ }
9004
+ }
9005
+ ],
9006
+ "post": {
9007
+ "tags": [
9008
+ "Key Custody"
9009
+ ],
9010
+ "summary": "Threshold signing, round 2 — aggregate and return the signature",
9011
+ "description": "The vault produces its share, verifies the caller's, aggregates, and\nverifies the result under the group key before returning it. A bad\nshare is a `400`, never a published signature.\n",
9012
+ "operationId": "tssSignComplete",
9013
+ "security": [
9014
+ {
9015
+ "BearerAuth": []
9016
+ }
9017
+ ],
9018
+ "requestBody": {
9019
+ "required": true,
9020
+ "content": {
9021
+ "application/json": {
9022
+ "schema": {
9023
+ "type": "object",
9024
+ "required": [
9025
+ "session_id",
9026
+ "client_commitments",
9027
+ "client_signature_share"
9028
+ ],
9029
+ "properties": {
9030
+ "session_id": {
9031
+ "type": "string",
9032
+ "format": "uuid"
9033
+ },
9034
+ "client_commitments": {
9035
+ "type": "string"
9036
+ },
9037
+ "client_signature_share": {
9038
+ "type": "string"
9039
+ }
9040
+ }
9041
+ }
9042
+ }
9043
+ }
9044
+ },
9045
+ "responses": {
9046
+ "200": {
9047
+ "description": "Signature",
9048
+ "content": {
9049
+ "application/json": {
9050
+ "schema": {
9051
+ "type": "object",
9052
+ "properties": {
9053
+ "key_id": {
9054
+ "type": "string",
9055
+ "format": "uuid"
9056
+ },
9057
+ "message_digest": {
9058
+ "type": "string"
9059
+ },
9060
+ "signature": {
9061
+ "type": "string",
9062
+ "description": "Base64 64-byte Ed25519 signature."
9063
+ },
9064
+ "signature_hex": {
9065
+ "type": "string"
9066
+ }
9067
+ }
9068
+ }
9069
+ }
9070
+ }
9071
+ },
9072
+ "400": {
9073
+ "$ref": "#/components/responses/BadRequest"
9074
+ },
9075
+ "401": {
9076
+ "$ref": "#/components/responses/Unauthorized"
9077
+ },
9078
+ "404": {
9079
+ "$ref": "#/components/responses/NotFound"
9080
+ },
9081
+ "409": {
9082
+ "$ref": "#/components/responses/Conflict"
9083
+ }
9084
+ }
9085
+ }
9086
+ },
9087
+ "/v1/treasury/wallets/{chain}/tss/prepare": {
9088
+ "parameters": [
9089
+ {
9090
+ "name": "chain",
9091
+ "in": "path",
9092
+ "required": true,
9093
+ "schema": {
9094
+ "type": "string"
9095
+ }
9096
+ }
9097
+ ],
9098
+ "post": {
9099
+ "tags": [
9100
+ "Key Custody"
9101
+ ],
9102
+ "summary": "Build the unsigned message for a send from a client_tss wallet",
9103
+ "description": "Runs wallet access, the sanctions screen and spend policies on the\ndeclared destination, fetches a recent blockhash and returns the\nunsigned transaction message. Sign it with `/v1/keys/{key_id}/tss/sign/*`\nand submit with `…/tss/broadcast`.\n",
9104
+ "operationId": "tssTreasuryPrepare",
9105
+ "security": [
9106
+ {
9107
+ "BearerAuth": []
9108
+ }
9109
+ ],
9110
+ "requestBody": {
9111
+ "required": true,
9112
+ "content": {
9113
+ "application/json": {
9114
+ "schema": {
9115
+ "type": "object",
9116
+ "required": [
9117
+ "to",
9118
+ "value"
9119
+ ],
9120
+ "properties": {
9121
+ "to": {
9122
+ "type": "string"
9123
+ },
9124
+ "value": {
9125
+ "type": "string",
9126
+ "description": "Major units",
9127
+ "e.g. \"0.5\".": null
9128
+ },
9129
+ "memo": {
9130
+ "type": "string"
9131
+ }
9132
+ }
9133
+ }
9134
+ }
9135
+ }
9136
+ },
9137
+ "responses": {
9138
+ "200": {
9139
+ "description": "Unsigned message",
9140
+ "content": {
9141
+ "application/json": {
9142
+ "schema": {
9143
+ "type": "object",
9144
+ "properties": {
9145
+ "key_id": {
9146
+ "type": "string",
9147
+ "format": "uuid"
9148
+ },
9149
+ "chain": {
9150
+ "type": "string"
9151
+ },
9152
+ "from": {
9153
+ "type": "string"
9154
+ },
9155
+ "to": {
9156
+ "type": "string"
9157
+ },
9158
+ "value_base_units": {
9159
+ "type": "string"
9160
+ },
9161
+ "recent_blockhash": {
9162
+ "type": "string"
9163
+ },
9164
+ "message": {
9165
+ "type": "string"
9166
+ },
9167
+ "message_digest": {
9168
+ "type": "string"
9169
+ }
9170
+ }
9171
+ }
9172
+ }
9173
+ }
9174
+ },
9175
+ "400": {
9176
+ "$ref": "#/components/responses/BadRequest"
9177
+ },
9178
+ "401": {
9179
+ "$ref": "#/components/responses/Unauthorized"
9180
+ },
9181
+ "403": {
9182
+ "$ref": "#/components/responses/Forbidden"
9183
+ },
9184
+ "404": {
9185
+ "$ref": "#/components/responses/NotFound"
9186
+ }
9187
+ }
9188
+ }
9189
+ },
9190
+ "/v1/treasury/wallets/{chain}/tss/broadcast": {
9191
+ "parameters": [
9192
+ {
9193
+ "name": "chain",
9194
+ "in": "path",
9195
+ "required": true,
9196
+ "schema": {
9197
+ "type": "string"
9198
+ }
9199
+ }
9200
+ ],
9201
+ "post": {
9202
+ "tags": [
9203
+ "Key Custody"
9204
+ ],
9205
+ "summary": "Broadcast a threshold-signed send",
9206
+ "description": "Verifies the signature under the wallet's public key over exactly this\nmessage, checks `to` is a transfer destination inside it, assembles the\ntransaction and submits it. Audited as `treasury_wallet.send`.\n",
9207
+ "operationId": "tssTreasuryBroadcast",
9208
+ "security": [
9209
+ {
9210
+ "BearerAuth": []
9211
+ }
9212
+ ],
9213
+ "requestBody": {
9214
+ "required": true,
9215
+ "content": {
9216
+ "application/json": {
9217
+ "schema": {
9218
+ "type": "object",
9219
+ "required": [
9220
+ "message",
9221
+ "signature",
9222
+ "to",
9223
+ "value_base_units"
9224
+ ],
9225
+ "properties": {
9226
+ "message": {
9227
+ "type": "string"
9228
+ },
9229
+ "signature": {
9230
+ "type": "string"
9231
+ },
9232
+ "to": {
9233
+ "type": "string"
9234
+ },
9235
+ "value_base_units": {
9236
+ "type": "string"
9237
+ }
9238
+ }
9239
+ }
9240
+ }
9241
+ }
9242
+ },
9243
+ "responses": {
9244
+ "200": {
9245
+ "description": "Broadcast",
9246
+ "content": {
9247
+ "application/json": {
9248
+ "schema": {
9249
+ "$ref": "#/components/schemas/TreasuryWalletSendResponse"
9250
+ }
9251
+ }
9252
+ }
9253
+ },
9254
+ "400": {
9255
+ "$ref": "#/components/responses/BadRequest"
9256
+ },
9257
+ "401": {
9258
+ "$ref": "#/components/responses/Unauthorized"
9259
+ },
9260
+ "404": {
9261
+ "$ref": "#/components/responses/NotFound"
9262
+ }
9263
+ }
9264
+ }
9265
+ },
8416
9266
  "/v1/treasury/wallets/generate": {
8417
9267
  "post": {
8418
9268
  "tags": [
@@ -31957,6 +32807,14 @@
31957
32807
  "type": "string",
31958
32808
  "format": "date-time",
31959
32809
  "nullable": true
32810
+ },
32811
+ "custody": {
32812
+ "type": "string",
32813
+ "enum": [
32814
+ "server",
32815
+ "client_tss"
32816
+ ],
32817
+ "description": "`server` — 1claw holds the whole private key and can sign alone.\n`client_tss` — 2-party threshold key; the customer's passkey share is required.\n"
31960
32818
  }
31961
32819
  }
31962
32820
  },
@@ -34460,6 +35318,14 @@
34460
35318
  "created_at": {
34461
35319
  "type": "string",
34462
35320
  "format": "date-time"
35321
+ },
35322
+ "custody": {
35323
+ "type": "string",
35324
+ "enum": [
35325
+ "server",
35326
+ "client_tss"
35327
+ ],
35328
+ "description": "`server` — 1claw holds the whole private key and can sign alone.\n`client_tss` — 2-party threshold key; the customer's passkey share is required.\n"
34463
35329
  }
34464
35330
  }
34465
35331
  },
@@ -38161,6 +39027,120 @@
38161
39027
  },
38162
39028
  "name": {
38163
39029
  "type": "string"
39030
+ },
39031
+ "prf_supported": {
39032
+ "type": "boolean",
39033
+ "nullable": true,
39034
+ "description": "`prf.enabled` from `credential.getClientExtensionResults()` —\nwhether this authenticator can derive the secret that wraps a\nwallet share. Omit if the client did not request the extension.\n"
39035
+ }
39036
+ }
39037
+ },
39038
+ "PutClientShareRequest": {
39039
+ "type": "object",
39040
+ "required": [
39041
+ "wrap_kind",
39042
+ "wrapped_share",
39043
+ "salt"
39044
+ ],
39045
+ "properties": {
39046
+ "wrap_kind": {
39047
+ "type": "string",
39048
+ "enum": [
39049
+ "passkey_prf",
39050
+ "recovery_code"
39051
+ ]
39052
+ },
39053
+ "credential_id": {
39054
+ "type": "string",
39055
+ "format": "uuid",
39056
+ "nullable": true,
39057
+ "description": "Required for `passkey_prf`; the passkey id from `GET /v1/auth/passkeys`."
39058
+ },
39059
+ "wrapped_share": {
39060
+ "type": "string",
39061
+ "description": "Base64 ciphertext (≤ 4 KiB). Opaque to the vault."
39062
+ },
39063
+ "salt": {
39064
+ "type": "string",
39065
+ "description": "Base64 PRF salt, 16–64 random bytes, one per key."
39066
+ }
39067
+ }
39068
+ },
39069
+ "ClientShareResponse": {
39070
+ "type": "object",
39071
+ "properties": {
39072
+ "id": {
39073
+ "type": "string",
39074
+ "format": "uuid"
39075
+ },
39076
+ "key_id": {
39077
+ "type": "string",
39078
+ "format": "uuid"
39079
+ },
39080
+ "key_kind": {
39081
+ "type": "string",
39082
+ "enum": [
39083
+ "agent_signing_key",
39084
+ "treasury_wallet"
39085
+ ]
39086
+ },
39087
+ "wrap_kind": {
39088
+ "type": "string",
39089
+ "enum": [
39090
+ "passkey_prf",
39091
+ "recovery_code"
39092
+ ]
39093
+ },
39094
+ "credential_id": {
39095
+ "type": "string",
39096
+ "format": "uuid",
39097
+ "nullable": true
39098
+ },
39099
+ "wrapped_share": {
39100
+ "type": "string",
39101
+ "description": "Base64, exactly as stored."
39102
+ },
39103
+ "salt": {
39104
+ "type": "string",
39105
+ "description": "Base64."
39106
+ },
39107
+ "created_at": {
39108
+ "type": "string",
39109
+ "format": "date-time"
39110
+ },
39111
+ "updated_at": {
39112
+ "type": "string",
39113
+ "format": "date-time"
39114
+ }
39115
+ }
39116
+ },
39117
+ "ClientShareListResponse": {
39118
+ "type": "object",
39119
+ "properties": {
39120
+ "key_id": {
39121
+ "type": "string",
39122
+ "format": "uuid"
39123
+ },
39124
+ "key_kind": {
39125
+ "type": "string",
39126
+ "enum": [
39127
+ "agent_signing_key",
39128
+ "treasury_wallet"
39129
+ ]
39130
+ },
39131
+ "custody": {
39132
+ "type": "string",
39133
+ "enum": [
39134
+ "server",
39135
+ "client_tss"
39136
+ ],
39137
+ "description": "`server` — 1claw holds the whole private key and can sign alone.\n`client_tss` — 2-party threshold key; the customer's share is required.\n"
39138
+ },
39139
+ "shares": {
39140
+ "type": "array",
39141
+ "items": {
39142
+ "$ref": "#/components/schemas/ClientShareResponse"
39143
+ }
38164
39144
  }
38165
39145
  }
38166
39146
  },