tempo.ts 0.7.5 → 0.8.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.
Files changed (147) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/chains.d.ts +6 -20
  3. package/dist/chains.d.ts.map +1 -1
  4. package/dist/chains.js +14 -15
  5. package/dist/chains.js.map +1 -1
  6. package/dist/ox/KeyAuthorization.d.ts +356 -0
  7. package/dist/ox/KeyAuthorization.d.ts.map +1 -0
  8. package/dist/ox/KeyAuthorization.js +360 -0
  9. package/dist/ox/KeyAuthorization.js.map +1 -0
  10. package/dist/ox/SignatureEnvelope.d.ts +21 -6
  11. package/dist/ox/SignatureEnvelope.d.ts.map +1 -1
  12. package/dist/ox/SignatureEnvelope.js +43 -3
  13. package/dist/ox/SignatureEnvelope.js.map +1 -1
  14. package/dist/ox/Transaction.d.ts +5 -1
  15. package/dist/ox/Transaction.d.ts.map +1 -1
  16. package/dist/ox/Transaction.js +5 -0
  17. package/dist/ox/Transaction.js.map +1 -1
  18. package/dist/ox/TransactionEnvelopeAA.d.ts +9 -0
  19. package/dist/ox/TransactionEnvelopeAA.d.ts.map +1 -1
  20. package/dist/ox/TransactionEnvelopeAA.js +17 -4
  21. package/dist/ox/TransactionEnvelopeAA.js.map +1 -1
  22. package/dist/ox/TransactionRequest.d.ts +7 -1
  23. package/dist/ox/TransactionRequest.d.ts.map +1 -1
  24. package/dist/ox/TransactionRequest.js +12 -0
  25. package/dist/ox/TransactionRequest.js.map +1 -1
  26. package/dist/ox/index.d.ts +1 -0
  27. package/dist/ox/index.d.ts.map +1 -1
  28. package/dist/ox/index.js +1 -0
  29. package/dist/ox/index.js.map +1 -1
  30. package/dist/prool/Instance.js +1 -1
  31. package/dist/prool/Instance.js.map +1 -1
  32. package/{src/prool/internal → dist/prool}/chain.json +4 -2
  33. package/dist/viem/Abis.d.ts +319 -6
  34. package/dist/viem/Abis.d.ts.map +1 -1
  35. package/dist/viem/Abis.js +199 -7
  36. package/dist/viem/Abis.js.map +1 -1
  37. package/dist/viem/Account.d.ts +103 -14
  38. package/dist/viem/Account.d.ts.map +1 -1
  39. package/dist/viem/Account.js +177 -23
  40. package/dist/viem/Account.js.map +1 -1
  41. package/dist/viem/Actions/account.d.ts.map +1 -1
  42. package/dist/viem/Actions/account.js +4 -5
  43. package/dist/viem/Actions/account.js.map +1 -1
  44. package/dist/viem/Actions/amm.d.ts +84 -32
  45. package/dist/viem/Actions/amm.d.ts.map +1 -1
  46. package/dist/viem/Actions/amm.js +12 -32
  47. package/dist/viem/Actions/amm.js.map +1 -1
  48. package/dist/viem/Actions/dex.d.ts +156 -4
  49. package/dist/viem/Actions/dex.d.ts.map +1 -1
  50. package/dist/viem/Actions/fee.d.ts +4 -0
  51. package/dist/viem/Actions/fee.d.ts.map +1 -1
  52. package/dist/viem/Actions/reward.d.ts +78 -0
  53. package/dist/viem/Actions/reward.d.ts.map +1 -1
  54. package/dist/viem/Actions/token.d.ts +585 -0
  55. package/dist/viem/Actions/token.d.ts.map +1 -1
  56. package/dist/viem/Actions/token.js +2 -2
  57. package/dist/viem/Actions/token.js.map +1 -1
  58. package/dist/viem/Addresses.d.ts +1 -1
  59. package/dist/viem/Addresses.d.ts.map +1 -1
  60. package/dist/viem/Addresses.js +1 -1
  61. package/dist/viem/Addresses.js.map +1 -1
  62. package/dist/viem/Chain.d.ts +35 -0
  63. package/dist/viem/Chain.d.ts.map +1 -1
  64. package/dist/viem/Chain.js +37 -0
  65. package/dist/viem/Chain.js.map +1 -1
  66. package/dist/viem/Decorator.d.ts +193 -16
  67. package/dist/viem/Decorator.d.ts.map +1 -1
  68. package/dist/viem/Decorator.js +7 -0
  69. package/dist/viem/Decorator.js.map +1 -1
  70. package/dist/viem/Formatters.d.ts.map +1 -1
  71. package/dist/viem/Formatters.js +8 -7
  72. package/dist/viem/Formatters.js.map +1 -1
  73. package/dist/viem/Storage.d.ts +1 -0
  74. package/dist/viem/Storage.d.ts.map +1 -1
  75. package/dist/viem/Storage.js +21 -0
  76. package/dist/viem/Storage.js.map +1 -1
  77. package/dist/viem/TokenIds.d.ts +1 -1
  78. package/dist/viem/TokenIds.d.ts.map +1 -1
  79. package/dist/viem/TokenIds.js +1 -1
  80. package/dist/viem/TokenIds.js.map +1 -1
  81. package/dist/viem/Transaction.d.ts +9 -1
  82. package/dist/viem/Transaction.d.ts.map +1 -1
  83. package/dist/viem/Transaction.js +2 -1
  84. package/dist/viem/Transaction.js.map +1 -1
  85. package/dist/viem/WebAuthnP256.d.ts +4 -1
  86. package/dist/viem/WebAuthnP256.d.ts.map +1 -1
  87. package/dist/viem/WebAuthnP256.js +3 -1
  88. package/dist/viem/WebAuthnP256.js.map +1 -1
  89. package/dist/wagmi/Actions/amm.d.ts +6 -16
  90. package/dist/wagmi/Actions/amm.d.ts.map +1 -1
  91. package/dist/wagmi/Actions/amm.js +6 -16
  92. package/dist/wagmi/Actions/amm.js.map +1 -1
  93. package/dist/wagmi/Connector.d.ts +25 -8
  94. package/dist/wagmi/Connector.d.ts.map +1 -1
  95. package/dist/wagmi/Connector.js +120 -27
  96. package/dist/wagmi/Connector.js.map +1 -1
  97. package/dist/wagmi/Hooks/amm.d.ts +6 -16
  98. package/dist/wagmi/Hooks/amm.d.ts.map +1 -1
  99. package/dist/wagmi/Hooks/amm.js +6 -16
  100. package/dist/wagmi/Hooks/amm.js.map +1 -1
  101. package/package.json +3 -2
  102. package/src/chains.ts +14 -15
  103. package/src/ox/KeyAuthorization.test.ts +1332 -0
  104. package/src/ox/KeyAuthorization.ts +542 -0
  105. package/src/ox/SignatureEnvelope.test.ts +624 -0
  106. package/src/ox/SignatureEnvelope.ts +89 -9
  107. package/src/ox/Transaction.test.ts +214 -0
  108. package/src/ox/Transaction.ts +13 -1
  109. package/src/ox/TransactionEnvelopeAA.test.ts +164 -4
  110. package/src/ox/TransactionEnvelopeAA.ts +36 -3
  111. package/src/ox/TransactionRequest.ts +22 -1
  112. package/src/ox/e2e.test.ts +612 -5
  113. package/src/ox/index.ts +1 -0
  114. package/src/prool/Instance.ts +1 -1
  115. package/src/prool/chain.json +238 -0
  116. package/src/server/Handler.test.ts +20 -36
  117. package/src/viem/Abis.ts +200 -7
  118. package/src/viem/Account.test.ts +444 -0
  119. package/src/viem/Account.ts +355 -42
  120. package/src/viem/Actions/account.ts +3 -5
  121. package/src/viem/Actions/amm.test.ts +220 -1
  122. package/src/viem/Actions/amm.ts +12 -32
  123. package/src/viem/Actions/token.test.ts +8 -8
  124. package/src/viem/Actions/token.ts +2 -2
  125. package/src/viem/Addresses.ts +1 -1
  126. package/src/viem/Chain.test.ts +168 -0
  127. package/src/viem/Chain.ts +37 -1
  128. package/src/viem/Decorator.ts +214 -16
  129. package/src/viem/Formatters.ts +8 -7
  130. package/src/viem/Storage.ts +22 -0
  131. package/src/viem/TokenIds.ts +1 -1
  132. package/src/viem/Transaction.ts +14 -2
  133. package/src/viem/WebAuthnP256.ts +8 -2
  134. package/src/viem/e2e.test.ts +299 -96
  135. package/src/wagmi/Actions/amm.test.ts +93 -2
  136. package/src/wagmi/Actions/amm.ts +6 -16
  137. package/src/wagmi/Connector.test.ts +1 -1
  138. package/src/wagmi/Connector.ts +184 -54
  139. package/src/wagmi/Hooks/amm.test.ts +335 -0
  140. package/src/wagmi/Hooks/amm.ts +6 -16
  141. package/src/wagmi/Hooks/fee.test.ts +10 -4
  142. package/src/wagmi/Hooks/token.test.ts +0 -488
  143. package/dist/viem/internal/account.d.ts +0 -21
  144. package/dist/viem/internal/account.d.ts.map +0 -1
  145. package/dist/viem/internal/account.js +0 -61
  146. package/dist/viem/internal/account.js.map +0 -1
  147. package/src/viem/internal/account.ts +0 -89
@@ -7,10 +7,10 @@ import {
7
7
  WebCryptoP256,
8
8
  } from 'ox'
9
9
  import { getTransactionCount } from 'viem/actions'
10
- import { expect, test } from 'vitest'
10
+ import { beforeEach, describe, expect, test } from 'vitest'
11
11
  import { chainId } from '../../test/config.js'
12
12
  import { client, fundAddress } from '../../test/viem/config.js'
13
- import { SignatureEnvelope } from './index.js'
13
+ import { KeyAuthorization, SignatureEnvelope } from './index.js'
14
14
  import * as Transaction from './Transaction.js'
15
15
  import * as TransactionEnvelopeAA from './TransactionEnvelopeAA.js'
16
16
  import * as TransactionReceipt from './TransactionReceipt.js'
@@ -75,7 +75,6 @@ test('behavior: default (secp256k1)', async () => {
75
75
  hash,
76
76
  feeToken: _,
77
77
  from,
78
- // @ts-expect-error
79
78
  keyAuthorization: __,
80
79
  nonce,
81
80
  maxFeePerGas,
@@ -215,7 +214,6 @@ test('behavior: default (p256)', async () => {
215
214
  chainId,
216
215
  feeToken: _,
217
216
  from,
218
- // @ts-expect-error
219
217
  keyAuthorization: __,
220
218
  hash,
221
219
  nonce,
@@ -501,7 +499,6 @@ test('behavior: default (webauthn)', async () => {
501
499
  chainId,
502
500
  feeToken: _,
503
501
  from,
504
- // @ts-expect-error
505
502
  keyAuthorization: __,
506
503
  hash,
507
504
  nonce,
@@ -703,3 +700,613 @@ test('behavior: feePayerSignature (user → feePayer)', async () => {
703
700
  expect(feeToken).toBe('0x20c0000000000000000000000000000000000001')
704
701
  expect(from).toBe(senderAddress)
705
702
  })
703
+
704
+ describe('behavior: keyAuthorization', () => {
705
+ const privateKey = Secp256k1.randomPrivateKey()
706
+ const address = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey }))
707
+ const root = {
708
+ address,
709
+ privateKey,
710
+ } as const
711
+
712
+ beforeEach(async () => {
713
+ await fundAddress(client, {
714
+ address,
715
+ })
716
+ })
717
+
718
+ test('behavior: secp256k1 access key', async () => {
719
+ const privateKey =
720
+ '0x06a952d58c24d287245276dd8b4272d82a921d27d90874a6c27a3bc19ff4bfde'
721
+ const publicKey = Secp256k1.getPublicKey({ privateKey })
722
+ const address = Address.fromPublicKey(publicKey)
723
+ const access = {
724
+ address,
725
+ publicKey,
726
+ privateKey,
727
+ } as const
728
+
729
+ const keyAuth = KeyAuthorization.from({
730
+ address: access.address,
731
+ type: 'secp256k1',
732
+ })
733
+
734
+ const keyAuth_signature = Secp256k1.sign({
735
+ payload: KeyAuthorization.getSignPayload(keyAuth),
736
+ privateKey: root.privateKey,
737
+ })
738
+
739
+ const keyAuth_signed = KeyAuthorization.from(keyAuth, {
740
+ signature: SignatureEnvelope.from(keyAuth_signature),
741
+ })
742
+
743
+ const nonce = await getTransactionCount(client, {
744
+ address: root.address,
745
+ blockTag: 'pending',
746
+ })
747
+
748
+ const transaction = TransactionEnvelopeAA.from({
749
+ calls: [
750
+ {
751
+ to: '0x0000000000000000000000000000000000000000',
752
+ },
753
+ ],
754
+ chainId,
755
+ feeToken: '0x20c0000000000000000000000000000000000001',
756
+ keyAuthorization: keyAuth_signed,
757
+ nonce: BigInt(nonce),
758
+ gas: 100_000n,
759
+ maxFeePerGas: Value.fromGwei('20'),
760
+ maxPriorityFeePerGas: Value.fromGwei('10'),
761
+ })
762
+
763
+ const signature = Secp256k1.sign({
764
+ payload: TransactionEnvelopeAA.getSignPayload(transaction),
765
+ privateKey: access.privateKey,
766
+ })
767
+
768
+ const serialized_signed = TransactionEnvelopeAA.serialize(transaction, {
769
+ signature: SignatureEnvelope.from({
770
+ userAddress: root.address,
771
+ inner: SignatureEnvelope.from(signature),
772
+ type: 'keychain',
773
+ }),
774
+ })
775
+
776
+ const receipt = (await client
777
+ .request({
778
+ method: 'eth_sendRawTransactionSync',
779
+ params: [serialized_signed],
780
+ })
781
+ .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
782
+
783
+ {
784
+ const response = await client
785
+ .request({
786
+ method: 'eth_getTransactionByHash',
787
+ params: [receipt.transactionHash],
788
+ })
789
+ .then((tx) => Transaction.fromRpc(tx as any))
790
+ if (!response) throw new Error()
791
+
792
+ const {
793
+ blockNumber,
794
+ blockHash,
795
+ chainId: _,
796
+ gasPrice,
797
+ hash,
798
+ from,
799
+ keyAuthorization,
800
+ maxFeePerGas,
801
+ maxPriorityFeePerGas,
802
+ nonce,
803
+ signature,
804
+ transactionIndex,
805
+ ...rest
806
+ } = response
807
+
808
+ expect(blockNumber).toBeDefined()
809
+ expect(blockHash).toBeDefined()
810
+ expect(gasPrice).toBeDefined()
811
+ expect(maxFeePerGas).toBeDefined()
812
+ expect(maxPriorityFeePerGas).toBeDefined()
813
+ expect(nonce).toBeDefined()
814
+ expect(from).toBe(root.address)
815
+ expect(hash).toBe(receipt.transactionHash)
816
+ expect(keyAuthorization).toBeDefined()
817
+ expect(signature).toBeDefined()
818
+ expect(transactionIndex).toBeDefined()
819
+ expect(rest).toMatchInlineSnapshot(`
820
+ {
821
+ "aaAuthorizationList": [],
822
+ "accessList": [],
823
+ "calls": [
824
+ {
825
+ "data": "0x",
826
+ "to": "0x0000000000000000000000000000000000000000",
827
+ "value": 0n,
828
+ },
829
+ ],
830
+ "data": undefined,
831
+ "feePayerSignature": null,
832
+ "feeToken": "0x20c0000000000000000000000000000000000001",
833
+ "gas": 100000n,
834
+ "nonceKey": 0n,
835
+ "type": "aa",
836
+ "validAfter": null,
837
+ "validBefore": null,
838
+ "value": 0n,
839
+ }
840
+ `)
841
+ }
842
+
843
+ const {
844
+ blockNumber,
845
+ blockHash,
846
+ feePayer,
847
+ feeToken,
848
+ from,
849
+ logs,
850
+ logsBloom,
851
+ transactionHash,
852
+ transactionIndex,
853
+ ...rest
854
+ } = receipt
855
+
856
+ expect(blockNumber).toBeDefined()
857
+ expect(blockHash).toBeDefined()
858
+ expect(feeToken).toBeDefined()
859
+ expect(feePayer).toBeDefined()
860
+ expect(from).toBeDefined()
861
+ expect(logs).toBeDefined()
862
+ expect(logsBloom).toBeDefined()
863
+ expect(transactionHash).toBe(receipt.transactionHash)
864
+ expect(transactionIndex).toBeDefined()
865
+ expect(rest).toMatchInlineSnapshot(`
866
+ {
867
+ "blobGasPrice": undefined,
868
+ "blobGasUsed": undefined,
869
+ "contractAddress": null,
870
+ "cumulativeGasUsed": 23600n,
871
+ "effectiveGasPrice": 20000000000n,
872
+ "gasUsed": 23600n,
873
+ "status": "success",
874
+ "to": "0x0000000000000000000000000000000000000000",
875
+ "type": "0x76",
876
+ }
877
+ `)
878
+
879
+ // Test a subsequent tx signed by access key with no keyAuthorization
880
+ {
881
+ const nonce = await getTransactionCount(client, {
882
+ address: root.address,
883
+ blockTag: 'pending',
884
+ })
885
+
886
+ const transaction = TransactionEnvelopeAA.from({
887
+ calls: [
888
+ {
889
+ to: '0x0000000000000000000000000000000000000000',
890
+ },
891
+ ],
892
+ chainId,
893
+ feeToken: '0x20c0000000000000000000000000000000000001',
894
+ nonce: BigInt(nonce),
895
+ gas: 100_000n,
896
+ maxFeePerGas: Value.fromGwei('20'),
897
+ maxPriorityFeePerGas: Value.fromGwei('10'),
898
+ })
899
+
900
+ const signature = Secp256k1.sign({
901
+ payload: TransactionEnvelopeAA.getSignPayload(transaction),
902
+ privateKey: access.privateKey,
903
+ })
904
+
905
+ const serialized_signed = TransactionEnvelopeAA.serialize(transaction, {
906
+ signature: SignatureEnvelope.from({
907
+ userAddress: root.address,
908
+ inner: SignatureEnvelope.from(signature),
909
+ type: 'keychain',
910
+ }),
911
+ })
912
+
913
+ const receipt = await client.request({
914
+ method: 'eth_sendRawTransactionSync',
915
+ params: [serialized_signed],
916
+ })
917
+
918
+ expect(receipt).toBeDefined()
919
+ }
920
+ })
921
+
922
+ test('behavior: p256 access key', async () => {
923
+ const privateKey =
924
+ '0x06a952d58c24d287245276dd8b4272d82a921d27d90874a6c27a3bc19ff4bfde'
925
+ const publicKey = P256.getPublicKey({ privateKey })
926
+ const address = Address.fromPublicKey(publicKey)
927
+ const access = {
928
+ address,
929
+ publicKey,
930
+ privateKey,
931
+ } as const
932
+
933
+ const keyAuth = KeyAuthorization.from({
934
+ address: access.address,
935
+ type: 'p256',
936
+ })
937
+
938
+ const keyAuth_signature = Secp256k1.sign({
939
+ payload: KeyAuthorization.getSignPayload(keyAuth),
940
+ privateKey: root.privateKey,
941
+ })
942
+
943
+ const keyAuth_signed = KeyAuthorization.from(keyAuth, {
944
+ signature: SignatureEnvelope.from(keyAuth_signature),
945
+ })
946
+
947
+ const nonce = await getTransactionCount(client, {
948
+ address: root.address,
949
+ blockTag: 'pending',
950
+ })
951
+
952
+ const transaction = TransactionEnvelopeAA.from({
953
+ calls: [
954
+ {
955
+ to: '0x0000000000000000000000000000000000000000',
956
+ },
957
+ ],
958
+ chainId,
959
+ feeToken: '0x20c0000000000000000000000000000000000001',
960
+ keyAuthorization: keyAuth_signed,
961
+ nonce: BigInt(nonce),
962
+ gas: 100_000n,
963
+ maxFeePerGas: Value.fromGwei('20'),
964
+ maxPriorityFeePerGas: Value.fromGwei('10'),
965
+ })
966
+
967
+ const signature = P256.sign({
968
+ payload: TransactionEnvelopeAA.getSignPayload(transaction),
969
+ privateKey: access.privateKey,
970
+ })
971
+
972
+ const serialized_signed = TransactionEnvelopeAA.serialize(transaction, {
973
+ signature: SignatureEnvelope.from({
974
+ userAddress: root.address,
975
+ inner: SignatureEnvelope.from({
976
+ prehash: false,
977
+ publicKey: access.publicKey,
978
+ signature,
979
+ type: 'p256',
980
+ }),
981
+ type: 'keychain',
982
+ }),
983
+ })
984
+
985
+ const receipt = (await client
986
+ .request({
987
+ method: 'eth_sendRawTransactionSync',
988
+ params: [serialized_signed],
989
+ })
990
+ .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
991
+ expect(receipt).toBeDefined()
992
+
993
+ {
994
+ const response = await client
995
+ .request({
996
+ method: 'eth_getTransactionByHash',
997
+ params: [receipt.transactionHash],
998
+ })
999
+ .then((tx) => Transaction.fromRpc(tx as any))
1000
+ if (!response) throw new Error()
1001
+
1002
+ const {
1003
+ blockNumber,
1004
+ blockHash,
1005
+ chainId: _,
1006
+ gasPrice,
1007
+ hash,
1008
+ from,
1009
+ keyAuthorization,
1010
+ maxFeePerGas,
1011
+ maxPriorityFeePerGas,
1012
+ nonce,
1013
+ signature,
1014
+ transactionIndex,
1015
+ ...rest
1016
+ } = response
1017
+
1018
+ expect(blockNumber).toBeDefined()
1019
+ expect(blockHash).toBeDefined()
1020
+ expect(gasPrice).toBeDefined()
1021
+ expect(hash).toBe(receipt.transactionHash)
1022
+ expect(from).toBe(root.address)
1023
+ expect(keyAuthorization).toBeDefined()
1024
+ expect(maxFeePerGas).toBeDefined()
1025
+ expect(maxPriorityFeePerGas).toBeDefined()
1026
+ expect(nonce).toBeDefined()
1027
+ expect(signature).toBeDefined()
1028
+ expect(transactionIndex).toBeDefined()
1029
+ expect(rest).toMatchInlineSnapshot(`
1030
+ {
1031
+ "aaAuthorizationList": [],
1032
+ "accessList": [],
1033
+ "calls": [
1034
+ {
1035
+ "data": "0x",
1036
+ "to": "0x0000000000000000000000000000000000000000",
1037
+ "value": 0n,
1038
+ },
1039
+ ],
1040
+ "data": undefined,
1041
+ "feePayerSignature": null,
1042
+ "feeToken": "0x20c0000000000000000000000000000000000001",
1043
+ "gas": 100000n,
1044
+ "nonceKey": 0n,
1045
+ "type": "aa",
1046
+ "validAfter": null,
1047
+ "validBefore": null,
1048
+ "value": 0n,
1049
+ }
1050
+ `)
1051
+ }
1052
+
1053
+ const {
1054
+ blockNumber,
1055
+ blockHash,
1056
+ feePayer,
1057
+ feeToken,
1058
+ from,
1059
+ logs,
1060
+ logsBloom,
1061
+ transactionHash,
1062
+ transactionIndex,
1063
+ ...rest
1064
+ } = receipt
1065
+
1066
+ expect(blockNumber).toBeDefined()
1067
+ expect(blockHash).toBeDefined()
1068
+ expect(feePayer).toBeDefined()
1069
+ expect(feeToken).toBeDefined()
1070
+ expect(from).toBeDefined()
1071
+ expect(logs).toBeDefined()
1072
+ expect(logsBloom).toBeDefined()
1073
+ expect(transactionHash).toBe(receipt.transactionHash)
1074
+ expect(transactionIndex).toBeDefined()
1075
+ expect(rest).toMatchInlineSnapshot(`
1076
+ {
1077
+ "blobGasPrice": undefined,
1078
+ "blobGasUsed": undefined,
1079
+ "contractAddress": null,
1080
+ "cumulativeGasUsed": 28600n,
1081
+ "effectiveGasPrice": 20000000000n,
1082
+ "gasUsed": 28600n,
1083
+ "status": "success",
1084
+ "to": "0x0000000000000000000000000000000000000000",
1085
+ "type": "0x76",
1086
+ }
1087
+ `)
1088
+
1089
+ // Test a subsequent tx signed by access key with no keyAuthorization
1090
+ {
1091
+ const nonce = await getTransactionCount(client, {
1092
+ address: root.address,
1093
+ blockTag: 'pending',
1094
+ })
1095
+
1096
+ const transaction = TransactionEnvelopeAA.from({
1097
+ calls: [
1098
+ {
1099
+ to: '0x0000000000000000000000000000000000000000',
1100
+ },
1101
+ ],
1102
+ chainId,
1103
+ feeToken: '0x20c0000000000000000000000000000000000001',
1104
+ nonce: BigInt(nonce),
1105
+ gas: 100_000n,
1106
+ maxFeePerGas: Value.fromGwei('20'),
1107
+ maxPriorityFeePerGas: Value.fromGwei('10'),
1108
+ })
1109
+
1110
+ const signature = P256.sign({
1111
+ payload: TransactionEnvelopeAA.getSignPayload(transaction),
1112
+ privateKey: access.privateKey,
1113
+ })
1114
+
1115
+ const serialized_signed = TransactionEnvelopeAA.serialize(transaction, {
1116
+ signature: SignatureEnvelope.from({
1117
+ userAddress: root.address,
1118
+ inner: SignatureEnvelope.from({
1119
+ prehash: false,
1120
+ publicKey: access.publicKey,
1121
+ signature,
1122
+ type: 'p256',
1123
+ }),
1124
+ type: 'keychain',
1125
+ }),
1126
+ })
1127
+
1128
+ const receipt = await client.request({
1129
+ method: 'eth_sendRawTransactionSync',
1130
+ params: [serialized_signed],
1131
+ })
1132
+
1133
+ expect(receipt).toBeDefined()
1134
+ }
1135
+ })
1136
+
1137
+ test('behavior: webcrypto access key', async () => {
1138
+ const keyPair = await WebCryptoP256.createKeyPair()
1139
+ const address = Address.fromPublicKey(keyPair.publicKey)
1140
+ const access = {
1141
+ address,
1142
+ publicKey: keyPair.publicKey,
1143
+ privateKey: keyPair.privateKey,
1144
+ } as const
1145
+
1146
+ const keyAuth = KeyAuthorization.from({
1147
+ address: access.address,
1148
+ type: 'p256',
1149
+ })
1150
+
1151
+ const keyAuth_signature = Secp256k1.sign({
1152
+ payload: KeyAuthorization.getSignPayload(keyAuth),
1153
+ privateKey: root.privateKey,
1154
+ })
1155
+
1156
+ const keyAuth_signed = KeyAuthorization.from(keyAuth, {
1157
+ signature: SignatureEnvelope.from(keyAuth_signature),
1158
+ })
1159
+
1160
+ const nonce = await getTransactionCount(client, {
1161
+ address: root.address,
1162
+ blockTag: 'pending',
1163
+ })
1164
+
1165
+ const transaction = TransactionEnvelopeAA.from({
1166
+ calls: [
1167
+ {
1168
+ to: '0x0000000000000000000000000000000000000000',
1169
+ },
1170
+ ],
1171
+ chainId,
1172
+ feeToken: '0x20c0000000000000000000000000000000000001',
1173
+ keyAuthorization: keyAuth_signed,
1174
+ nonce: BigInt(nonce),
1175
+ gas: 100_000n,
1176
+ maxFeePerGas: Value.fromGwei('20'),
1177
+ maxPriorityFeePerGas: Value.fromGwei('10'),
1178
+ })
1179
+
1180
+ const signature = await WebCryptoP256.sign({
1181
+ payload: TransactionEnvelopeAA.getSignPayload(transaction),
1182
+ privateKey: keyPair.privateKey,
1183
+ })
1184
+
1185
+ const serialized_signed = TransactionEnvelopeAA.serialize(transaction, {
1186
+ signature: SignatureEnvelope.from({
1187
+ userAddress: root.address,
1188
+ inner: SignatureEnvelope.from({
1189
+ prehash: true,
1190
+ publicKey: access.publicKey,
1191
+ signature,
1192
+ type: 'p256',
1193
+ }),
1194
+ type: 'keychain',
1195
+ }),
1196
+ })
1197
+
1198
+ const receipt = await client.request({
1199
+ method: 'eth_sendRawTransactionSync',
1200
+ params: [serialized_signed],
1201
+ })
1202
+
1203
+ expect(receipt).toBeDefined()
1204
+
1205
+ {
1206
+ const response = await client
1207
+ .request({
1208
+ method: 'eth_getTransactionByHash',
1209
+ params: [receipt.transactionHash],
1210
+ })
1211
+ .then((tx) => Transaction.fromRpc(tx as any))
1212
+ if (!response) throw new Error()
1213
+
1214
+ const {
1215
+ blockNumber,
1216
+ blockHash,
1217
+ chainId: _,
1218
+ gasPrice,
1219
+ hash,
1220
+ from,
1221
+ keyAuthorization,
1222
+ maxFeePerGas,
1223
+ maxPriorityFeePerGas,
1224
+ nonce,
1225
+ signature,
1226
+ transactionIndex,
1227
+ ...rest
1228
+ } = response
1229
+
1230
+ expect(blockNumber).toBeDefined()
1231
+ expect(blockHash).toBeDefined()
1232
+ expect(gasPrice).toBeDefined()
1233
+ expect(hash).toBe(receipt.transactionHash)
1234
+ expect(from).toBe(root.address)
1235
+ expect(keyAuthorization).toBeDefined()
1236
+ expect(maxFeePerGas).toBeDefined()
1237
+ expect(maxPriorityFeePerGas).toBeDefined()
1238
+ expect(nonce).toBeDefined()
1239
+ expect(signature).toBeDefined()
1240
+ expect(transactionIndex).toBeDefined()
1241
+ expect(rest).toMatchInlineSnapshot(`
1242
+ {
1243
+ "aaAuthorizationList": [],
1244
+ "accessList": [],
1245
+ "calls": [
1246
+ {
1247
+ "data": "0x",
1248
+ "to": "0x0000000000000000000000000000000000000000",
1249
+ "value": 0n,
1250
+ },
1251
+ ],
1252
+ "data": undefined,
1253
+ "feePayerSignature": null,
1254
+ "feeToken": "0x20c0000000000000000000000000000000000001",
1255
+ "gas": 100000n,
1256
+ "nonceKey": 0n,
1257
+ "type": "aa",
1258
+ "validAfter": null,
1259
+ "validBefore": null,
1260
+ "value": 0n,
1261
+ }
1262
+ `)
1263
+ }
1264
+
1265
+ // Test a subsequent tx signed by access key with no keyAuthorization
1266
+ {
1267
+ const nonce = await getTransactionCount(client, {
1268
+ address: root.address,
1269
+ blockTag: 'pending',
1270
+ })
1271
+
1272
+ const transaction = TransactionEnvelopeAA.from({
1273
+ calls: [
1274
+ {
1275
+ to: '0x0000000000000000000000000000000000000000',
1276
+ },
1277
+ ],
1278
+ chainId,
1279
+ feeToken: '0x20c0000000000000000000000000000000000001',
1280
+ nonce: BigInt(nonce),
1281
+ gas: 100_000n,
1282
+ maxFeePerGas: Value.fromGwei('20'),
1283
+ maxPriorityFeePerGas: Value.fromGwei('10'),
1284
+ })
1285
+
1286
+ const signature = await WebCryptoP256.sign({
1287
+ payload: TransactionEnvelopeAA.getSignPayload(transaction),
1288
+ privateKey: keyPair.privateKey,
1289
+ })
1290
+
1291
+ const serialized_signed = TransactionEnvelopeAA.serialize(transaction, {
1292
+ signature: SignatureEnvelope.from({
1293
+ userAddress: root.address,
1294
+ inner: SignatureEnvelope.from({
1295
+ prehash: true,
1296
+ publicKey: access.publicKey,
1297
+ signature,
1298
+ type: 'p256',
1299
+ }),
1300
+ type: 'keychain',
1301
+ }),
1302
+ })
1303
+
1304
+ const receipt = await client.request({
1305
+ method: 'eth_sendRawTransactionSync',
1306
+ params: [serialized_signed],
1307
+ })
1308
+
1309
+ expect(receipt).toBeDefined()
1310
+ }
1311
+ })
1312
+ })
package/src/ox/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * as KeyAuthorization from './KeyAuthorization.js'
1
2
  export * as Order from './Order.js'
2
3
  export * as OrdersFilters from './OrdersFilters.js'
3
4
  export * as Pagination from './Pagination.js'
@@ -22,7 +22,7 @@ export const tempo = defineInstance((parameters: tempo.Parameters = {}) => {
22
22
  const {
23
23
  builder,
24
24
  containerName = `tempo.${crypto.randomUUID()}`,
25
- chain = path.resolve(import.meta.dirname, './internal/chain.json'),
25
+ chain = path.resolve(import.meta.dirname, './chain.json'),
26
26
  image = 'ghcr.io/tempoxyz/tempo',
27
27
  dev,
28
28
  log: log_,