ox 0.14.55 → 0.14.57

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 (97) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/_cjs/tempo/{MultisigConfig.js → AccountConfig.js} +32 -9
  3. package/_cjs/tempo/AccountConfig.js.map +1 -0
  4. package/_cjs/tempo/{MultisigOperation.js → AccountOperation.js} +29 -29
  5. package/_cjs/tempo/AccountOperation.js.map +1 -0
  6. package/_cjs/tempo/{MultisigSimulation.js → AccountSimulation.js} +22 -13
  7. package/_cjs/tempo/AccountSimulation.js.map +1 -0
  8. package/_cjs/tempo/KeyAuthorization.js +10 -18
  9. package/_cjs/tempo/KeyAuthorization.js.map +1 -1
  10. package/_cjs/tempo/SignatureEnvelope.js +64 -64
  11. package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
  12. package/_cjs/tempo/TransactionRequest.js +15 -10
  13. package/_cjs/tempo/TransactionRequest.js.map +1 -1
  14. package/_cjs/tempo/index.js +4 -4
  15. package/_cjs/tempo/index.js.map +1 -1
  16. package/_cjs/version.js +1 -1
  17. package/_esm/tempo/{MultisigConfig.js → AccountConfig.js} +161 -64
  18. package/_esm/tempo/AccountConfig.js.map +1 -0
  19. package/_esm/tempo/{MultisigOperation.js → AccountOperation.js} +64 -64
  20. package/_esm/tempo/AccountOperation.js.map +1 -0
  21. package/_esm/tempo/{MultisigSimulation.js → AccountSimulation.js} +35 -25
  22. package/_esm/tempo/AccountSimulation.js.map +1 -0
  23. package/_esm/tempo/KeyAuthorization.js +16 -19
  24. package/_esm/tempo/KeyAuthorization.js.map +1 -1
  25. package/_esm/tempo/SignatureEnvelope.js +71 -71
  26. package/_esm/tempo/SignatureEnvelope.js.map +1 -1
  27. package/_esm/tempo/TransactionRequest.js +15 -10
  28. package/_esm/tempo/TransactionRequest.js.map +1 -1
  29. package/_esm/tempo/index.js +50 -48
  30. package/_esm/tempo/index.js.map +1 -1
  31. package/_esm/version.js +1 -1
  32. package/_types/tempo/{MultisigConfig.d.ts → AccountConfig.d.ts} +156 -66
  33. package/_types/tempo/AccountConfig.d.ts.map +1 -0
  34. package/_types/tempo/{MultisigOperation.d.ts → AccountOperation.d.ts} +62 -62
  35. package/_types/tempo/AccountOperation.d.ts.map +1 -0
  36. package/_types/tempo/{MultisigSimulation.d.ts → AccountSimulation.d.ts} +25 -21
  37. package/_types/tempo/AccountSimulation.d.ts.map +1 -0
  38. package/_types/tempo/KeyAuthorization.d.ts +28 -23
  39. package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
  40. package/_types/tempo/RpcSchemaTempo.d.ts +13 -13
  41. package/_types/tempo/RpcSchemaTempo.d.ts.map +1 -1
  42. package/_types/tempo/SignatureEnvelope.d.ts +36 -33
  43. package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
  44. package/_types/tempo/TransactionRequest.d.ts +11 -9
  45. package/_types/tempo/TransactionRequest.d.ts.map +1 -1
  46. package/_types/tempo/index.d.ts +50 -48
  47. package/_types/tempo/index.d.ts.map +1 -1
  48. package/_types/version.d.ts +1 -1
  49. package/package.json +31 -31
  50. package/tempo/AccountConfig/package.json +6 -0
  51. package/tempo/AccountConfig.test-d/package.json +6 -0
  52. package/tempo/AccountConfig.test-d.ts +72 -0
  53. package/tempo/AccountConfig.test.ts +642 -0
  54. package/tempo/{MultisigConfig.ts → AccountConfig.ts} +212 -75
  55. package/tempo/AccountOperation/package.json +6 -0
  56. package/tempo/AccountOperation.test-d/package.json +6 -0
  57. package/tempo/AccountOperation.test-d.ts +71 -0
  58. package/tempo/{MultisigOperation.test.ts → AccountOperation.test.ts} +129 -129
  59. package/tempo/{MultisigOperation.ts → AccountOperation.ts} +95 -97
  60. package/tempo/AccountSimulation/package.json +6 -0
  61. package/tempo/AccountSimulation.test-d/package.json +6 -0
  62. package/tempo/{MultisigSimulation.test-d.ts → AccountSimulation.test-d.ts} +7 -9
  63. package/tempo/{MultisigSimulation.test.ts → AccountSimulation.test.ts} +73 -29
  64. package/tempo/{MultisigSimulation.ts → AccountSimulation.ts} +47 -35
  65. package/tempo/KeyAuthorization.test-d.ts +19 -29
  66. package/tempo/KeyAuthorization.test.ts +151 -74
  67. package/tempo/KeyAuthorization.ts +40 -61
  68. package/tempo/RpcSchemaTempo.test-d.ts +20 -20
  69. package/tempo/RpcSchemaTempo.ts +13 -13
  70. package/tempo/SignatureEnvelope.test-d.ts +7 -7
  71. package/tempo/SignatureEnvelope.test.ts +34 -34
  72. package/tempo/SignatureEnvelope.ts +107 -103
  73. package/tempo/Transaction.test.ts +4 -4
  74. package/tempo/TransactionRequest.test-d.ts +17 -8
  75. package/tempo/TransactionRequest.test.ts +31 -21
  76. package/tempo/TransactionRequest.ts +29 -20
  77. package/tempo/{multisig.e2e.test.ts → configurableAccounts.e2e.test.ts} +16 -16
  78. package/tempo/index.ts +50 -48
  79. package/version.ts +1 -1
  80. package/_cjs/tempo/MultisigConfig.js.map +0 -1
  81. package/_cjs/tempo/MultisigOperation.js.map +0 -1
  82. package/_cjs/tempo/MultisigSimulation.js.map +0 -1
  83. package/_esm/tempo/MultisigConfig.js.map +0 -1
  84. package/_esm/tempo/MultisigOperation.js.map +0 -1
  85. package/_esm/tempo/MultisigSimulation.js.map +0 -1
  86. package/_types/tempo/MultisigConfig.d.ts.map +0 -1
  87. package/_types/tempo/MultisigOperation.d.ts.map +0 -1
  88. package/_types/tempo/MultisigSimulation.d.ts.map +0 -1
  89. package/tempo/MultisigConfig/package.json +0 -6
  90. package/tempo/MultisigConfig.test-d/package.json +0 -6
  91. package/tempo/MultisigConfig.test-d.ts +0 -52
  92. package/tempo/MultisigConfig.test.ts +0 -391
  93. package/tempo/MultisigOperation/package.json +0 -6
  94. package/tempo/MultisigOperation.test-d/package.json +0 -6
  95. package/tempo/MultisigOperation.test-d.ts +0 -71
  96. package/tempo/MultisigSimulation/package.json +0 -6
  97. package/tempo/MultisigSimulation.test-d/package.json +0 -6
@@ -8,8 +8,8 @@ import {
8
8
  WebAuthnP256,
9
9
  } from 'ox'
10
10
  import { describe, expect, test } from 'vitest'
11
+ import * as AccountConfig from './AccountConfig.js'
11
12
  import * as KeyAuthorization from './KeyAuthorization.js'
12
- import * as MultisigConfig from './MultisigConfig.js'
13
13
  import * as Period from './Period.js'
14
14
  import * as SignatureEnvelope from './SignatureEnvelope.js'
15
15
 
@@ -71,9 +71,9 @@ const signature_webauthn = SignatureEnvelope.from({
71
71
  },
72
72
  })
73
73
 
74
- const signature_multisig = {
74
+ const signature_configurable = {
75
75
  account: address,
76
- config: MultisigConfig.from({
76
+ config: AccountConfig.from({
77
77
  owners: [
78
78
  {
79
79
  owner: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
@@ -84,9 +84,9 @@ const signature_multisig = {
84
84
  version: 1n,
85
85
  }),
86
86
  signatures: [SignatureEnvelope.from(signature_secp256k1)],
87
- type: 'multisig',
88
- } as const satisfies SignatureEnvelope.Multisig
89
- const signature_multisig_rpc =
87
+ type: 'configurable',
88
+ } as const satisfies SignatureEnvelope.Configurable
89
+ const signature_configurable_rpc =
90
90
  '0xf89794be95c3f554e9fc85ec51be69a3d807a0d55bcf2cf83ba000000000000000000000000000000000000000000000000000000000000000000101d7d694f39fd6e51aad88f6f4ce6ab8827279cfffb9226601f843b841fa78c5905fb0b9d6066ef531f962a62bc6ef0d5eb59ecb134056d206f75aaed7780926ff2601a935c2c79707d9e1799948c9f19dcdde1e090e903b19a07923d01c' as const
91
91
 
92
92
  const signature_keychain = {
@@ -95,10 +95,15 @@ const signature_keychain = {
95
95
  userAddress: address,
96
96
  } as const satisfies SignatureEnvelope.Keychain
97
97
 
98
- describe('multisig account binding', () => {
98
+ describe('configurable account binding', () => {
99
99
  test('resolves Tempo account bindings before encoding', () => {
100
100
  const signed = KeyAuthorization.from(
101
- { account: `tempox${address}`, address, chainId: 1n, type: 'multisig' },
101
+ {
102
+ account: `tempox${address}`,
103
+ address,
104
+ chainId: 1n,
105
+ type: 'configurable',
106
+ },
102
107
  { signature: signature_secp256k1 },
103
108
  )
104
109
  expect(signed.account).toMatchInlineSnapshot(
@@ -112,45 +117,84 @@ describe('multisig account binding', () => {
112
117
  ).toMatchInlineSnapshot(`"0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c"`)
113
118
  })
114
119
 
115
- test('rejects unbound grants before signing or encoding', () => {
116
- const authorization = { address, chainId: 1n, type: 'multisig' } as const
117
- const signed = {
118
- ...authorization,
119
- signature: SignatureEnvelope.from(signature_secp256k1),
120
- }
121
- for (const encode of [
122
- // @ts-expect-error Deliberately unbound multisig grant.
123
- () => KeyAuthorization.from(authorization),
124
- // @ts-expect-error Deliberately unbound multisig grant.
125
- () => KeyAuthorization.toTuple(authorization),
126
- // @ts-expect-error Deliberately unbound multisig grant.
127
- () => KeyAuthorization.getSignPayload(authorization),
128
- // @ts-expect-error Deliberately unbound multisig grant.
129
- () => KeyAuthorization.serialize(authorization),
130
- // @ts-expect-error Deliberately unbound multisig grant.
131
- () => KeyAuthorization.toRpc(signed),
132
- ])
133
- expect(encode).toThrowErrorMatchingInlineSnapshot(
134
- `[KeyAuthorization.MissingAccountError: Multisig key grants require a parent account binding.]`,
135
- )
120
+ test('behavior: accepts unbound configurable grants', () => {
121
+ // The node binds a root-signed grant to its signer, so only admin-signed
122
+ // grants need `account` (TIP-1049).
123
+ const signed = KeyAuthorization.from(
124
+ { address, chainId: 1n, type: 'configurable' },
125
+ { signature: signature_secp256k1 },
126
+ )
127
+ const rpc = KeyAuthorization.toRpc(signed)
128
+ expect({
129
+ deserialized: KeyAuthorization.deserialize(
130
+ KeyAuthorization.serialize(signed),
131
+ ),
132
+ fromRpc: KeyAuthorization.fromRpc(rpc),
133
+ fromTuple: KeyAuthorization.fromTuple([['0x01', '0x03', address]]),
134
+ rpc,
135
+ }).toMatchInlineSnapshot(`
136
+ {
137
+ "deserialized": {
138
+ "account": undefined,
139
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
140
+ "chainId": 1n,
141
+ "signature": {
142
+ "signature": {
143
+ "r": 113291597329930009559670063131885256927775966057121513567941051428123344285399n,
144
+ "s": 54293712598725100598138577281441749550405991478212695085505730636505228583888n,
145
+ "yParity": 1,
146
+ },
147
+ "type": "secp256k1",
148
+ },
149
+ "type": "configurable",
150
+ },
151
+ "fromRpc": {
152
+ "account": undefined,
153
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
154
+ "chainId": 1n,
155
+ "limits": undefined,
156
+ "signature": {
157
+ "signature": {
158
+ "r": 113291597329930009559670063131885256927775966057121513567941051428123344285399n,
159
+ "s": 54293712598725100598138577281441749550405991478212695085505730636505228583888n,
160
+ "yParity": 1,
161
+ },
162
+ "type": "secp256k1",
163
+ },
164
+ "type": "configurable",
165
+ },
166
+ "fromTuple": {
167
+ "account": undefined,
168
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
169
+ "chainId": 1n,
170
+ "type": "configurable",
171
+ },
172
+ "rpc": {
173
+ "account": undefined,
174
+ "chainId": "0x1",
175
+ "expiry": null,
176
+ "keyId": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
177
+ "keyType": "configurableAccount",
178
+ "limits": undefined,
179
+ "signature": {
180
+ "r": "0xfa78c5905fb0b9d6066ef531f962a62bc6ef0d5eb59ecb134056d206f75aaed7",
181
+ "s": "0x780926ff2601a935c2c79707d9e1799948c9f19dcdde1e090e903b19a07923d0",
182
+ "type": "secp256k1",
183
+ "yParity": "0x1",
184
+ },
185
+ },
186
+ }
187
+ `)
136
188
  })
137
189
 
138
- test('rejects unbound RPC and RLP grants', () => {
190
+ test('behavior: preserves a bound account', () => {
139
191
  const signed = KeyAuthorization.from(
140
- { account: address, address, chainId: 1n, type: 'multisig' },
192
+ { account: address, address, chainId: 1n, type: 'configurable' },
141
193
  { signature: signature_secp256k1 },
142
194
  )
143
- const rpc = KeyAuthorization.toRpc(signed)
144
- for (const account of [undefined, null]) {
145
- // @ts-expect-error Deliberately unbound multisig grant.
146
- expect(() => KeyAuthorization.fromRpc({ ...rpc, account })).toThrowError(
147
- KeyAuthorization.MissingAccountError,
148
- )
149
- }
150
- expect(() =>
151
- KeyAuthorization.fromTuple([['0x01', '0x03', address]]),
152
- ).toThrowError(KeyAuthorization.MissingAccountError)
153
- expect(KeyAuthorization.fromRpc(rpc).account).toBe(address)
195
+ expect(
196
+ KeyAuthorization.fromRpc(KeyAuthorization.toRpc(signed)).account,
197
+ ).toBe(address)
154
198
  expect(
155
199
  KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)).account,
156
200
  ).toBe(address)
@@ -179,15 +223,15 @@ describe('from', () => {
179
223
  }).toEqual(limitsVectors)
180
224
  })
181
225
 
182
- test('accepts multisig grants and delegates', () => {
226
+ test('accepts configurable grants and delegates', () => {
183
227
  const signed = KeyAuthorization.from(
184
228
  {
185
229
  address,
186
230
  chainId: 1n,
187
- type: 'multisig',
188
- account: signature_multisig.account,
231
+ type: 'configurable',
232
+ account: signature_configurable.account,
189
233
  },
190
- { signature: signature_multisig },
234
+ { signature: signature_configurable },
191
235
  )
192
236
  expect(
193
237
  KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)),
@@ -587,7 +631,7 @@ describe('fromRpc', () => {
587
631
  `)
588
632
  })
589
633
 
590
- test('with signature (multisig)', () => {
634
+ test('with signature (configurable)', () => {
591
635
  const authorization = KeyAuthorization.from({
592
636
  address,
593
637
  chainId: 1n,
@@ -595,20 +639,20 @@ describe('fromRpc', () => {
595
639
  })
596
640
 
597
641
  const signed = KeyAuthorization.from(authorization, {
598
- signature: signature_multisig,
642
+ signature: signature_configurable,
599
643
  })
600
- expect(signed.signature).toEqual(signature_multisig)
644
+ expect(signed.signature).toEqual(signature_configurable)
601
645
  expect(
602
646
  KeyAuthorization.from(authorization, {
603
- signature: SignatureEnvelope.serialize(signature_multisig),
647
+ signature: SignatureEnvelope.serialize(signature_configurable),
604
648
  }).signature,
605
- ).toEqual(signature_multisig)
649
+ ).toEqual(signature_configurable)
606
650
  expect(
607
651
  KeyAuthorization.from({
608
652
  ...authorization,
609
- signature: signature_multisig,
653
+ signature: signature_configurable,
610
654
  }).signature,
611
- ).toEqual(signature_multisig)
655
+ ).toEqual(signature_configurable)
612
656
  expect(
613
657
  KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)),
614
658
  ).toEqual(signed)
@@ -626,7 +670,7 @@ describe('fromRpc', () => {
626
670
  signature: signature_keychain as never,
627
671
  }),
628
672
  ).toThrowErrorMatchingInlineSnapshot(
629
- `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`multisig\`.]`,
673
+ `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
630
674
  )
631
675
 
632
676
  expect(() =>
@@ -634,7 +678,7 @@ describe('fromRpc', () => {
634
678
  signature: SignatureEnvelope.serialize(signature_keychain),
635
679
  }),
636
680
  ).toThrowErrorMatchingInlineSnapshot(
637
- `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`multisig\`.]`,
681
+ `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
638
682
  )
639
683
 
640
684
  expect(() =>
@@ -643,19 +687,19 @@ describe('fromRpc', () => {
643
687
  signature: signature_keychain,
644
688
  } as never),
645
689
  ).toThrowErrorMatchingInlineSnapshot(
646
- `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`multisig\`.]`,
690
+ `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
647
691
  )
648
692
  })
649
693
  })
650
694
 
651
695
  describe('fromRpc', () => {
652
- test('behavior: multisig', () => {
696
+ test('behavior: configurable', () => {
653
697
  const authorization = KeyAuthorization.fromRpc({
654
698
  chainId: '0x1',
655
699
  expiry: null,
656
700
  keyId: address,
657
701
  keyType: 'secp256k1',
658
- signature: signature_multisig_rpc,
702
+ signature: signature_configurable_rpc,
659
703
  })
660
704
 
661
705
  expect(authorization.signature).toMatchInlineSnapshot(`
@@ -682,7 +726,7 @@ describe('fromRpc', () => {
682
726
  "type": "secp256k1",
683
727
  },
684
728
  ],
685
- "type": "multisig",
729
+ "type": "configurable",
686
730
  }
687
731
  `)
688
732
  })
@@ -697,7 +741,7 @@ describe('fromRpc', () => {
697
741
  signature: SignatureEnvelope.toRpc(signature_keychain),
698
742
  } as never),
699
743
  ).toThrowErrorMatchingInlineSnapshot(
700
- `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`multisig\`.]`,
744
+ `[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
701
745
  )
702
746
  })
703
747
 
@@ -934,13 +978,13 @@ describe('fromTuple', () => {
934
978
  `)
935
979
  })
936
980
 
937
- test('multisig', () => {
981
+ test('configurable', () => {
938
982
  const authorization = KeyAuthorization.fromTuple([
939
983
  ['0x1', '0x', address],
940
- SignatureEnvelope.serialize(signature_multisig),
984
+ SignatureEnvelope.serialize(signature_configurable),
941
985
  ])
942
986
 
943
- expect(authorization.signature).toEqual(signature_multisig)
987
+ expect(authorization.signature).toEqual(signature_configurable)
944
988
  })
945
989
 
946
990
  test('default', () => {
@@ -1280,7 +1324,7 @@ describe('getSignPayload', () => {
1280
1324
  })
1281
1325
 
1282
1326
  describe('deserialize', () => {
1283
- test('example: matches the frozen multisig witness vector', () => {
1327
+ test('example: matches the frozen configurable witness vector', () => {
1284
1328
  const serialized =
1285
1329
  '0xf8f1f85382107980941eff47bc3a10a45d4b230b5d10e37751fe6aa718808080a053535353535353535353535353535353535353535353535353535353535353538094c4a590afa7337e5cd5eb3aa60cacf91c5400044bb89a05f89794c4a590afa7337e5cd5eb3aa60cacf91c5400044bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b8412cfed9350faf80e4115e3c4c967356b80a8e6ee42e4a49ab953c8c8a3537d8d8359bf035a9bea18f32b0da7129cdce3ce701abc09ad8919b93da21a0d57e21451b' as const
1286
1330
  const authorization = KeyAuthorization.deserialize(serialized)
@@ -1313,7 +1357,7 @@ describe('deserialize', () => {
1313
1357
  "type": "secp256k1",
1314
1358
  },
1315
1359
  ],
1316
- "type": "multisig",
1360
+ "type": "configurable",
1317
1361
  },
1318
1362
  "type": "secp256k1",
1319
1363
  "witness": "0x5353535353535353535353535353535353535353535353535353535353535353",
@@ -1322,14 +1366,14 @@ describe('deserialize', () => {
1322
1366
  expect(KeyAuthorization.serialize(authorization)).toBe(serialized)
1323
1367
  })
1324
1368
 
1325
- test('multisig', () => {
1369
+ test('configurable', () => {
1326
1370
  const serialized = Rlp.fromHex([
1327
1371
  ['0x1', '0x', address],
1328
- SignatureEnvelope.serialize(signature_multisig),
1372
+ SignatureEnvelope.serialize(signature_configurable),
1329
1373
  ])
1330
1374
 
1331
1375
  expect(KeyAuthorization.deserialize(serialized).signature).toEqual(
1332
- signature_multisig,
1376
+ signature_configurable,
1333
1377
  )
1334
1378
  })
1335
1379
 
@@ -1503,16 +1547,28 @@ describe('serialize', () => {
1503
1547
  })
1504
1548
 
1505
1549
  describe('toRpc', () => {
1506
- test('behavior: multisig', () => {
1550
+ test('behavior: configurable key type uses the RPC configurableAccount key type', () => {
1551
+ const authorization = KeyAuthorization.from(
1552
+ { account: address, address, chainId: 1n, type: 'configurable' },
1553
+ { signature: signature_secp256k1 },
1554
+ )
1555
+ const rpc = KeyAuthorization.toRpc(authorization)
1556
+ expect(rpc.keyType).toMatchInlineSnapshot(`"configurableAccount"`)
1557
+ expect(KeyAuthorization.fromRpc(rpc).type).toMatchInlineSnapshot(
1558
+ `"configurable"`,
1559
+ )
1560
+ })
1561
+
1562
+ test('behavior: configurable', () => {
1507
1563
  const authorization = KeyAuthorization.toRpc({
1508
1564
  address,
1509
1565
  chainId: 1n,
1510
- signature: signature_multisig,
1566
+ signature: signature_configurable,
1511
1567
  type: 'secp256k1',
1512
1568
  })
1513
1569
 
1514
1570
  expect(authorization.signature).toMatchInlineSnapshot(
1515
- `"${signature_multisig_rpc}"`,
1571
+ `"${signature_configurable_rpc}"`,
1516
1572
  )
1517
1573
  })
1518
1574
 
@@ -1783,15 +1839,15 @@ describe('toTuple', () => {
1783
1839
  }
1784
1840
  })
1785
1841
 
1786
- test('multisig', () => {
1842
+ test('configurable', () => {
1787
1843
  const tuple = KeyAuthorization.toTuple({
1788
1844
  address,
1789
1845
  chainId: 1n,
1790
- signature: signature_multisig,
1846
+ signature: signature_configurable,
1791
1847
  type: 'secp256k1',
1792
1848
  })
1793
1849
 
1794
- expect(tuple[1]).toBe(SignatureEnvelope.serialize(signature_multisig))
1850
+ expect(tuple[1]).toBe(SignatureEnvelope.serialize(signature_configurable))
1795
1851
  })
1796
1852
 
1797
1853
  test('default', () => {
@@ -2870,4 +2926,25 @@ describe('admin keys (TIP-1049)', () => {
2870
2926
  })
2871
2927
  expect(KeyAuthorization.hash(a)).not.toBe(KeyAuthorization.hash(b))
2872
2928
  })
2929
+
2930
+ describe('configurable admin keys', () => {
2931
+ test('behavior: a configurable account may sign or be granted an admin key', () => {
2932
+ const signed = KeyAuthorization.from(
2933
+ {
2934
+ account: signature_configurable.account,
2935
+ address,
2936
+ chainId: 1n,
2937
+ isAdmin: true,
2938
+ type: 'configurable',
2939
+ },
2940
+ { signature: signature_configurable },
2941
+ )
2942
+ expect(
2943
+ KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)),
2944
+ ).toEqual(signed)
2945
+ expect(
2946
+ KeyAuthorization.fromRpc(KeyAuthorization.toRpc(signed)),
2947
+ ).toMatchObject({ isAdmin: true, type: 'configurable' })
2948
+ })
2949
+ })
2873
2950
  })