ox 0.14.1 → 0.14.3
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.
- package/CHANGELOG.md +12 -0
- package/_cjs/core/internal/webauthn.js +2 -2
- package/_cjs/core/internal/webauthn.js.map +1 -1
- package/_cjs/tempo/TempoAddress.js +9 -84
- package/_cjs/tempo/TempoAddress.js.map +1 -1
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_cjs/webauthn/Authentication.js +9 -5
- package/_cjs/webauthn/Authentication.js.map +1 -1
- package/_cjs/webauthn/Registration.js +8 -5
- package/_cjs/webauthn/Registration.js.map +1 -1
- package/_esm/core/internal/webauthn.js +5 -2
- package/_esm/core/internal/webauthn.js.map +1 -1
- package/_esm/tempo/AuthorizationTempo.js +17 -17
- package/_esm/tempo/TempoAddress.js +18 -118
- package/_esm/tempo/TempoAddress.js.map +1 -1
- package/_esm/tempo/TxEnvelopeTempo.js +12 -12
- package/_esm/tempo/index.js +12 -14
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_esm/webauthn/Authentication.js +12 -5
- package/_esm/webauthn/Authentication.js.map +1 -1
- package/_esm/webauthn/Registration.js +11 -5
- package/_esm/webauthn/Registration.js.map +1 -1
- package/_types/core/internal/webauthn.d.ts +4 -1
- package/_types/core/internal/webauthn.d.ts.map +1 -1
- package/_types/tempo/AuthorizationTempo.d.ts +17 -17
- package/_types/tempo/TempoAddress.d.ts +14 -69
- package/_types/tempo/TempoAddress.d.ts.map +1 -1
- package/_types/tempo/TxEnvelopeTempo.d.ts +12 -12
- package/_types/tempo/index.d.ts +12 -14
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/_types/webauthn/Authentication.d.ts.map +1 -1
- package/_types/webauthn/Registration.d.ts.map +1 -1
- package/core/internal/webauthn.ts +4 -1
- package/package.json +1 -1
- package/tempo/AuthorizationTempo.test.ts +1 -1
- package/tempo/AuthorizationTempo.ts +17 -17
- package/tempo/KeyAuthorization.test.ts +2 -2
- package/tempo/PoolId.test.ts +2 -2
- package/tempo/TempoAddress.test.ts +22 -191
- package/tempo/TempoAddress.ts +21 -139
- package/tempo/TokenId.test.ts +3 -3
- package/tempo/TxEnvelopeTempo.test.ts +4 -4
- package/tempo/TxEnvelopeTempo.ts +12 -12
- package/tempo/index.ts +12 -14
- package/version.ts +1 -1
- package/webauthn/Authentication.ts +14 -11
- package/webauthn/Registration.ts +17 -7
|
@@ -100,7 +100,7 @@ export type TupleListSigned = TupleList<true>
|
|
|
100
100
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
101
101
|
*
|
|
102
102
|
* const authorization = AuthorizationTempo.from({
|
|
103
|
-
* address: '
|
|
103
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
104
104
|
* chainId: 1,
|
|
105
105
|
* nonce: 69n,
|
|
106
106
|
* })
|
|
@@ -118,7 +118,7 @@ export type TupleListSigned = TupleList<true>
|
|
|
118
118
|
* const privateKey = Secp256k1.randomPrivateKey()
|
|
119
119
|
*
|
|
120
120
|
* const authorization = AuthorizationTempo.from({
|
|
121
|
-
* address: '
|
|
121
|
+
* address: 'tempox0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
122
122
|
* chainId: 1,
|
|
123
123
|
* nonce: 40n,
|
|
124
124
|
* })
|
|
@@ -148,7 +148,7 @@ export type TupleListSigned = TupleList<true>
|
|
|
148
148
|
* const { privateKey, publicKey } = P256.createKeyPair()
|
|
149
149
|
*
|
|
150
150
|
* const authorization = AuthorizationTempo.from({
|
|
151
|
-
* address: '
|
|
151
|
+
* address: 'tempox0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
152
152
|
* chainId: 1,
|
|
153
153
|
* nonce: 40n,
|
|
154
154
|
* })
|
|
@@ -183,7 +183,7 @@ export type TupleListSigned = TupleList<true>
|
|
|
183
183
|
* const { privateKey, publicKey } = await WebCryptoP256.createKeyPair()
|
|
184
184
|
*
|
|
185
185
|
* const authorization = AuthorizationTempo.from({
|
|
186
|
-
* address: '
|
|
186
|
+
* address: 'tempox0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
187
187
|
* chainId: 1,
|
|
188
188
|
* nonce: 40n,
|
|
189
189
|
* })
|
|
@@ -219,7 +219,7 @@ export type TupleListSigned = TupleList<true>
|
|
|
219
219
|
* const credential = await WebAuthnP256.createCredential({ name: 'Example' })
|
|
220
220
|
*
|
|
221
221
|
* const authorization = AuthorizationTempo.from({
|
|
222
|
-
* address: '
|
|
222
|
+
* address: 'tempox0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
223
223
|
* chainId: 1,
|
|
224
224
|
* nonce: 40n,
|
|
225
225
|
* })
|
|
@@ -300,7 +300,7 @@ export declare namespace from {
|
|
|
300
300
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
301
301
|
*
|
|
302
302
|
* const authorization = AuthorizationTempo.fromRpc({
|
|
303
|
-
* address: '
|
|
303
|
+
* address: 'tempox0x0000000000000000000000000000000000000000',
|
|
304
304
|
* chainId: '0x1',
|
|
305
305
|
* nonce: '0x1',
|
|
306
306
|
* signature: {
|
|
@@ -338,7 +338,7 @@ export declare namespace fromRpc {
|
|
|
338
338
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
339
339
|
*
|
|
340
340
|
* const authorizationList = AuthorizationTempo.fromRpcList([{
|
|
341
|
-
* address: '
|
|
341
|
+
* address: 'tempox0x0000000000000000000000000000000000000000',
|
|
342
342
|
* chainId: '0x1',
|
|
343
343
|
* nonce: '0x1',
|
|
344
344
|
* signature: {
|
|
@@ -522,7 +522,7 @@ export declare namespace fromTupleList {
|
|
|
522
522
|
* const privateKey = Secp256k1.randomPrivateKey()
|
|
523
523
|
*
|
|
524
524
|
* const authorization = AuthorizationTempo.from({
|
|
525
|
-
* address: '
|
|
525
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
526
526
|
* chainId: 1,
|
|
527
527
|
* nonce: 69n,
|
|
528
528
|
* })
|
|
@@ -550,7 +550,7 @@ export declare namespace fromTupleList {
|
|
|
550
550
|
* const { privateKey, publicKey } = P256.createKeyPair()
|
|
551
551
|
*
|
|
552
552
|
* const authorization = AuthorizationTempo.from({
|
|
553
|
-
* address: '
|
|
553
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
554
554
|
* chainId: 1,
|
|
555
555
|
* nonce: 69n,
|
|
556
556
|
* })
|
|
@@ -583,7 +583,7 @@ export declare namespace fromTupleList {
|
|
|
583
583
|
* const { privateKey, publicKey } = await WebCryptoP256.createKeyPair()
|
|
584
584
|
*
|
|
585
585
|
* const authorization = AuthorizationTempo.from({
|
|
586
|
-
* address: '
|
|
586
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
587
587
|
* chainId: 1,
|
|
588
588
|
* nonce: 69n,
|
|
589
589
|
* })
|
|
@@ -617,7 +617,7 @@ export declare namespace fromTupleList {
|
|
|
617
617
|
* const credential = await WebAuthnP256.createCredential({ name: 'Example' })
|
|
618
618
|
*
|
|
619
619
|
* const authorization = AuthorizationTempo.from({
|
|
620
|
-
* address: '
|
|
620
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
621
621
|
* chainId: 1,
|
|
622
622
|
* nonce: 69n,
|
|
623
623
|
* })
|
|
@@ -658,7 +658,7 @@ export declare namespace getSignPayload {
|
|
|
658
658
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
659
659
|
*
|
|
660
660
|
* const authorization = AuthorizationTempo.from({
|
|
661
|
-
* address: '
|
|
661
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
662
662
|
* chainId: 1,
|
|
663
663
|
* nonce: 69n,
|
|
664
664
|
* })
|
|
@@ -714,7 +714,7 @@ export declare namespace hash {
|
|
|
714
714
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
715
715
|
*
|
|
716
716
|
* const authorization = AuthorizationTempo.toRpc({
|
|
717
|
-
* address: '
|
|
717
|
+
* address: 'tempox0x0000000000000000000000000000000000000000',
|
|
718
718
|
* chainId: 1,
|
|
719
719
|
* nonce: 1n,
|
|
720
720
|
* signature: {
|
|
@@ -754,7 +754,7 @@ export declare namespace toRpc {
|
|
|
754
754
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
755
755
|
*
|
|
756
756
|
* const authorization = AuthorizationTempo.toRpcList([{
|
|
757
|
-
* address: '
|
|
757
|
+
* address: 'tempox0x0000000000000000000000000000000000000000',
|
|
758
758
|
* chainId: 1,
|
|
759
759
|
* nonce: 1n,
|
|
760
760
|
* signature: {
|
|
@@ -787,7 +787,7 @@ export declare namespace toRpcList {
|
|
|
787
787
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
788
788
|
*
|
|
789
789
|
* const authorization = AuthorizationTempo.from({
|
|
790
|
-
* address: '
|
|
790
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
791
791
|
* chainId: 1,
|
|
792
792
|
* nonce: 69n,
|
|
793
793
|
* })
|
|
@@ -836,12 +836,12 @@ export declare namespace toTuple {
|
|
|
836
836
|
* import { AuthorizationTempo } from 'ox/tempo'
|
|
837
837
|
*
|
|
838
838
|
* const authorization_1 = AuthorizationTempo.from({
|
|
839
|
-
* address: '
|
|
839
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
840
840
|
* chainId: 1,
|
|
841
841
|
* nonce: 69n,
|
|
842
842
|
* })
|
|
843
843
|
* const authorization_2 = AuthorizationTempo.from({
|
|
844
|
-
* address: '
|
|
844
|
+
* address: 'tempox0x1234567890abcdef1234567890abcdef12345678',
|
|
845
845
|
* chainId: 3,
|
|
846
846
|
* nonce: 20n,
|
|
847
847
|
* })
|
|
@@ -84,8 +84,8 @@ describe('from', () => {
|
|
|
84
84
|
})
|
|
85
85
|
|
|
86
86
|
test('tempo address input', () => {
|
|
87
|
-
const tempoAddr = '
|
|
88
|
-
const tempoToken = '
|
|
87
|
+
const tempoAddr = 'tempox0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
|
|
88
|
+
const tempoToken = 'tempox0x20c0000000000000000000000000000000000001'
|
|
89
89
|
|
|
90
90
|
const authorization = KeyAuthorization.from({
|
|
91
91
|
address: tempoAddr,
|
package/tempo/PoolId.test.ts
CHANGED
|
@@ -32,8 +32,8 @@ test('from', () => {
|
|
|
32
32
|
expect(poolId4).toBe(poolId1)
|
|
33
33
|
|
|
34
34
|
// Test with tempo address inputs
|
|
35
|
-
const tempoAddr0 = '
|
|
36
|
-
const tempoAddr1 = '
|
|
35
|
+
const tempoAddr0 = 'tempox0x20c0000000000000000000000000000000000000'
|
|
36
|
+
const tempoAddr1 = 'tempox0x20c0000000000000000000000000000000000001'
|
|
37
37
|
const poolId5 = PoolId.from({
|
|
38
38
|
userToken: tempoAddr0,
|
|
39
39
|
validatorToken: tempoAddr1,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Address
|
|
1
|
+
import { Address } from 'ox'
|
|
2
2
|
import { TempoAddress } from 'ox/tempo'
|
|
3
3
|
import { describe, expect, test } from 'vitest'
|
|
4
4
|
|
|
@@ -15,17 +15,12 @@ describe('resolve', () => {
|
|
|
15
15
|
const tempoAddr = TempoAddress.format(rawAddress)
|
|
16
16
|
expect(TempoAddress.resolve(tempoAddr)).toBe(rawAddress)
|
|
17
17
|
})
|
|
18
|
-
|
|
19
|
-
test('tempo zone address', () => {
|
|
20
|
-
const tempoAddr = TempoAddress.format(rawAddress, { zoneId: 1 })
|
|
21
|
-
expect(TempoAddress.resolve(tempoAddr)).toBe(rawAddress)
|
|
22
|
-
})
|
|
23
18
|
})
|
|
24
19
|
|
|
25
20
|
describe('format', () => {
|
|
26
|
-
test('
|
|
21
|
+
test('default', () => {
|
|
27
22
|
expect(TempoAddress.format(rawAddress)).toMatchInlineSnapshot(
|
|
28
|
-
`"
|
|
23
|
+
`"tempox0x742d35cc6634c0532925a3b844bc9e7595f2bd28"`,
|
|
29
24
|
)
|
|
30
25
|
})
|
|
31
26
|
|
|
@@ -34,225 +29,61 @@ describe('format', () => {
|
|
|
34
29
|
expect(TempoAddress.format(tempoAddr)).toBe(tempoAddr)
|
|
35
30
|
})
|
|
36
31
|
|
|
37
|
-
test('zone address (zone ID = 1)', () => {
|
|
38
|
-
expect(
|
|
39
|
-
TempoAddress.format(rawAddress, { zoneId: 1 }),
|
|
40
|
-
).toMatchInlineSnapshot(
|
|
41
|
-
`"tempoz1qqqhgtf4e3nrfszn9yj68wzyhj08t90jh55q74d9uj"`,
|
|
42
|
-
)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test('zone address (zone ID = 252)', () => {
|
|
46
|
-
expect(
|
|
47
|
-
TempoAddress.format(rawAddress, { zoneId: 252 }),
|
|
48
|
-
).toMatchInlineSnapshot(
|
|
49
|
-
`"tempoz1qr78gtf4e3nrfszn9yj68wzyhj08t90jh55q9k62jd"`,
|
|
50
|
-
)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
test('zone address (zone ID = 253)', () => {
|
|
54
|
-
expect(
|
|
55
|
-
TempoAddress.format(rawAddress, { zoneId: 253 }),
|
|
56
|
-
).toMatchInlineSnapshot(
|
|
57
|
-
`"tempoz1qr7l6qr5956uce35cpfjjfdrhpzte8n4jhet62q0j8hus"`,
|
|
58
|
-
)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test('zone address (zone ID = 65535)', () => {
|
|
62
|
-
expect(
|
|
63
|
-
TempoAddress.format(rawAddress, { zoneId: 65535 }),
|
|
64
|
-
).toMatchInlineSnapshot(
|
|
65
|
-
`"tempoz1qr7lllm5956uce35cpfjjfdrhpzte8n4jhet62q8pdj6j"`,
|
|
66
|
-
)
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
test('zone address (zone ID = 65536)', () => {
|
|
70
|
-
expect(
|
|
71
|
-
TempoAddress.format(rawAddress, { zoneId: 65536 }),
|
|
72
|
-
).toMatchInlineSnapshot(
|
|
73
|
-
`"tempoz1qrlqqqqpqp6z6dwvvc6vq5efyk3ms39une6etu4a9qdupk5c"`,
|
|
74
|
-
)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('zone address (zone ID = 4294967295)', () => {
|
|
78
|
-
expect(
|
|
79
|
-
TempoAddress.format(rawAddress, { zoneId: 4294967295 }),
|
|
80
|
-
).toMatchInlineSnapshot(
|
|
81
|
-
`"tempoz1qrl0llllla6z6dwvvc6vq5efyk3ms39une6etu4a9qnk36qy"`,
|
|
82
|
-
)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
test('zone address (zone ID > 4294967295)', () => {
|
|
86
|
-
expect(
|
|
87
|
-
TempoAddress.format(rawAddress, { zoneId: BigInt('4294967296') }),
|
|
88
|
-
).toMatchInlineSnapshot(
|
|
89
|
-
`"tempoz1qrlsqqqqqqqsqqqqwskntnrxxnq9x2f95wuyf0y7wk2l90fg4306kk"`,
|
|
90
|
-
)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
32
|
test('lowercase output', () => {
|
|
94
33
|
const result = TempoAddress.format(rawAddress)
|
|
95
34
|
expect(result).toBe(result.toLowerCase())
|
|
96
35
|
})
|
|
97
36
|
|
|
98
|
-
test('
|
|
99
|
-
expect(TempoAddress.format(rawAddress)).toBe(
|
|
100
|
-
'tempo1qp6z6dwvvc6vq5efyk3ms39une6etu4a9qtj2kk0',
|
|
101
|
-
)
|
|
102
|
-
expect(TempoAddress.format(rawAddress, { zoneId: 1 })).toBe(
|
|
103
|
-
'tempoz1qqqhgtf4e3nrfszn9yj68wzyhj08t90jh55q74d9uj',
|
|
104
|
-
)
|
|
105
|
-
expect(TempoAddress.format(rawAddress, { zoneId: 1000 })).toBe(
|
|
106
|
-
'tempoz1qr77sqm5956uce35cpfjjfdrhpzte8n4jhet62qxx4zvx',
|
|
107
|
-
)
|
|
108
|
-
expect(TempoAddress.format(rawAddress, { zoneId: 100000 })).toBe(
|
|
109
|
-
'tempoz1qrl2ppspqp6z6dwvvc6vq5efyk3ms39une6etu4a9qg5477g',
|
|
110
|
-
)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
test('address lengths match spec', () => {
|
|
114
|
-
expect(TempoAddress.format(rawAddress).length).toBe(46)
|
|
115
|
-
expect(TempoAddress.format(rawAddress, { zoneId: 1 }).length).toBe(49)
|
|
116
|
-
expect(TempoAddress.format(rawAddress, { zoneId: 1000 }).length).toBe(52)
|
|
117
|
-
expect(TempoAddress.format(rawAddress, { zoneId: 100000 }).length).toBe(55)
|
|
37
|
+
test('address length', () => {
|
|
38
|
+
expect(TempoAddress.format(rawAddress).length).toBe(48)
|
|
118
39
|
})
|
|
119
40
|
})
|
|
120
41
|
|
|
121
42
|
describe('parse', () => {
|
|
122
|
-
test('
|
|
43
|
+
test('default', () => {
|
|
123
44
|
const encoded = TempoAddress.format(rawAddress)
|
|
124
45
|
expect(TempoAddress.parse(encoded)).toMatchInlineSnapshot(`
|
|
125
46
|
{
|
|
126
47
|
"address": "0x742d35CC6634c0532925a3B844bc9e7595F2Bd28",
|
|
127
|
-
"zoneId": undefined,
|
|
128
|
-
}
|
|
129
|
-
`)
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
test('zone (zone ID = 1)', () => {
|
|
133
|
-
const encoded = TempoAddress.format(rawAddress, { zoneId: 1 })
|
|
134
|
-
expect(TempoAddress.parse(encoded)).toMatchInlineSnapshot(`
|
|
135
|
-
{
|
|
136
|
-
"address": "0x742d35CC6634c0532925a3B844bc9e7595F2Bd28",
|
|
137
|
-
"zoneId": 1n,
|
|
138
|
-
}
|
|
139
|
-
`)
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
test('zone (zone ID = 252)', () => {
|
|
143
|
-
const encoded = TempoAddress.format(rawAddress, { zoneId: 252 })
|
|
144
|
-
expect(TempoAddress.parse(encoded)).toMatchInlineSnapshot(`
|
|
145
|
-
{
|
|
146
|
-
"address": "0x742d35CC6634c0532925a3B844bc9e7595F2Bd28",
|
|
147
|
-
"zoneId": 252n,
|
|
148
|
-
}
|
|
149
|
-
`)
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
test('zone (zone ID = 253)', () => {
|
|
153
|
-
const encoded = TempoAddress.format(rawAddress, { zoneId: 253 })
|
|
154
|
-
expect(TempoAddress.parse(encoded)).toMatchInlineSnapshot(`
|
|
155
|
-
{
|
|
156
|
-
"address": "0x742d35CC6634c0532925a3B844bc9e7595F2Bd28",
|
|
157
|
-
"zoneId": 253n,
|
|
158
|
-
}
|
|
159
|
-
`)
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
test('zone (zone ID = 65535)', () => {
|
|
163
|
-
const encoded = TempoAddress.format(rawAddress, { zoneId: 65535 })
|
|
164
|
-
expect(TempoAddress.parse(encoded)).toMatchInlineSnapshot(`
|
|
165
|
-
{
|
|
166
|
-
"address": "0x742d35CC6634c0532925a3B844bc9e7595F2Bd28",
|
|
167
|
-
"zoneId": 65535n,
|
|
168
48
|
}
|
|
169
49
|
`)
|
|
170
50
|
})
|
|
171
51
|
|
|
172
|
-
test('
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
"zoneId": 65536n,
|
|
178
|
-
}
|
|
179
|
-
`)
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
test('zone (large zone ID)', () => {
|
|
183
|
-
const encoded = TempoAddress.format(rawAddress, {
|
|
184
|
-
zoneId: BigInt('18446744073709551615'),
|
|
185
|
-
})
|
|
186
|
-
expect(TempoAddress.parse(encoded)).toMatchInlineSnapshot(`
|
|
187
|
-
{
|
|
188
|
-
"address": "0x742d35CC6634c0532925a3B844bc9e7595F2Bd28",
|
|
189
|
-
"zoneId": 18446744073709551615n,
|
|
190
|
-
}
|
|
191
|
-
`)
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
test('all uppercase', () => {
|
|
195
|
-
const encoded = TempoAddress.format(rawAddress)
|
|
196
|
-
const upper = encoded.toUpperCase()
|
|
197
|
-
expect(TempoAddress.parse(upper).address).toBe(rawAddress)
|
|
52
|
+
test('uppercase hex', () => {
|
|
53
|
+
expect(
|
|
54
|
+
TempoAddress.parse('tempox0x742D35CC6634C0532925A3B844BC9E7595F2BD28')
|
|
55
|
+
.address,
|
|
56
|
+
).toBe(rawAddress)
|
|
198
57
|
})
|
|
199
58
|
|
|
200
59
|
test('error: invalid prefix', () => {
|
|
201
|
-
const encoded = Bech32m.encode('bitcoin', new Uint8Array(20))
|
|
202
60
|
expect(() =>
|
|
203
|
-
TempoAddress.parse(
|
|
61
|
+
TempoAddress.parse('bitcoin0x742d35cc6634c0532925a3b844bc9e7595f2bd28'),
|
|
204
62
|
).toThrowErrorMatchingInlineSnapshot(
|
|
205
|
-
`[TempoAddress.InvalidPrefixError: Tempo address "
|
|
63
|
+
`[TempoAddress.InvalidPrefixError: Tempo address "bitcoin0x742d35cc6634c0532925a3b844bc9e7595f2bd28" has an invalid prefix. Expected "tempox".]`,
|
|
206
64
|
)
|
|
207
65
|
})
|
|
208
66
|
|
|
209
|
-
test('error:
|
|
210
|
-
|
|
211
|
-
const encoded = Bech32m.encode('tempo', data)
|
|
212
|
-
expect(() => TempoAddress.parse(encoded)).toThrow(
|
|
213
|
-
TempoAddress.InvalidVersionError,
|
|
214
|
-
)
|
|
67
|
+
test('error: invalid hex', () => {
|
|
68
|
+
expect(() => TempoAddress.parse('tempox0xinvalid')).toThrow()
|
|
215
69
|
})
|
|
216
70
|
|
|
217
|
-
test('error:
|
|
218
|
-
|
|
219
|
-
const tampered = encoded.slice(0, -1) + (encoded.endsWith('q') ? 'p' : 'q')
|
|
220
|
-
expect(() =>
|
|
221
|
-
TempoAddress.parse(tampered),
|
|
222
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
223
|
-
`[TempoAddress.InvalidChecksumError: Tempo address "${tampered}" has an invalid checksum.]`,
|
|
224
|
-
)
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
test('error: prefix swap detected', () => {
|
|
228
|
-
const mainnet = TempoAddress.format(rawAddress)
|
|
229
|
-
const swapped = 'tempoz1' + mainnet.slice(6)
|
|
230
|
-
expect(() =>
|
|
231
|
-
TempoAddress.parse(swapped),
|
|
232
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
233
|
-
`[TempoAddress.InvalidChecksumError: Tempo address "tempoz1qp6z6dwvvc6vq5efyk3ms39une6etu4a9qtj2kk0" has an invalid checksum.]`,
|
|
234
|
-
)
|
|
71
|
+
test('error: missing 0x prefix', () => {
|
|
72
|
+
expect(() => TempoAddress.parse('tempox742d35cc')).toThrow()
|
|
235
73
|
})
|
|
236
74
|
})
|
|
237
75
|
|
|
238
76
|
describe('validate', () => {
|
|
239
|
-
test('valid
|
|
77
|
+
test('valid address', () => {
|
|
240
78
|
const encoded = TempoAddress.format(rawAddress)
|
|
241
|
-
expect(TempoAddress.validate(encoded)).
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
test('valid zone address', () => {
|
|
245
|
-
const encoded = TempoAddress.format(rawAddress, { zoneId: 1 })
|
|
246
|
-
expect(TempoAddress.validate(encoded)).toMatchInlineSnapshot(`true`)
|
|
79
|
+
expect(TempoAddress.validate(encoded)).toBe(true)
|
|
247
80
|
})
|
|
248
81
|
|
|
249
82
|
test('invalid address', () => {
|
|
250
|
-
expect(TempoAddress.validate('invalid')).
|
|
83
|
+
expect(TempoAddress.validate('invalid')).toBe(false)
|
|
251
84
|
})
|
|
252
85
|
|
|
253
|
-
test('
|
|
254
|
-
|
|
255
|
-
const tampered = encoded.slice(0, -1) + (encoded.endsWith('q') ? 'p' : 'q')
|
|
256
|
-
expect(TempoAddress.validate(tampered)).toMatchInlineSnapshot(`false`)
|
|
86
|
+
test('invalid hex', () => {
|
|
87
|
+
expect(TempoAddress.validate('tempox0xinvalid')).toBe(false)
|
|
257
88
|
})
|
|
258
89
|
})
|
package/tempo/TempoAddress.ts
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
import * as core_Address from '../core/Address.js'
|
|
2
|
-
import * as Bech32m from '../core/Bech32m.js'
|
|
3
|
-
import * as Bytes from '../core/Bytes.js'
|
|
4
|
-
import * as CompactSize from '../core/CompactSize.js'
|
|
5
2
|
import * as Errors from '../core/Errors.js'
|
|
6
3
|
import * as Hex from '../core/Hex.js'
|
|
7
4
|
import type { Compute } from '../core/internal/types.js'
|
|
8
5
|
|
|
9
|
-
/** An address that can be either an Ethereum hex address or a Tempo
|
|
6
|
+
/** An address that can be either an Ethereum hex address or a Tempo address. */
|
|
10
7
|
export type Address = core_Address.Address | Tempo
|
|
11
8
|
|
|
12
9
|
/** Root type for a Tempo Address. */
|
|
13
|
-
export type Tempo = Compute<`
|
|
10
|
+
export type Tempo = Compute<`tempox${string}`>
|
|
14
11
|
|
|
15
12
|
/**
|
|
16
|
-
* Resolves an address input (either an Ethereum hex address or a Tempo
|
|
13
|
+
* Resolves an address input (either an Ethereum hex address or a Tempo address)
|
|
17
14
|
* to an Ethereum hex address.
|
|
18
15
|
*
|
|
19
16
|
* @example
|
|
20
17
|
* ```ts twoslash
|
|
21
18
|
* import { TempoAddress } from 'ox/tempo'
|
|
22
19
|
*
|
|
23
|
-
* const address = TempoAddress.resolve('
|
|
20
|
+
* const address = TempoAddress.resolve('tempox0x742d35cc6634c0532925a3b844bc9e7595f2bd28')
|
|
24
21
|
* // @log: '0x742d35CC6634c0532925a3B844bc9e7595F2Bd28'
|
|
25
22
|
* ```
|
|
26
23
|
*
|
|
@@ -33,7 +30,7 @@ export type Tempo = Compute<`tempo1${string}` | `tempoz1${string}`>
|
|
|
33
30
|
* // @log: '0x742d35CC6634c0532925a3B844bc9e7595F2Bd28'
|
|
34
31
|
* ```
|
|
35
32
|
*
|
|
36
|
-
* @param address - An Ethereum hex address or Tempo
|
|
33
|
+
* @param address - An Ethereum hex address or Tempo address.
|
|
37
34
|
* @returns The resolved Ethereum hex address.
|
|
38
35
|
*/
|
|
39
36
|
export function resolve(address: Address): core_Address.Address {
|
|
@@ -42,140 +39,63 @@ export function resolve(address: Address): core_Address.Address {
|
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
/**
|
|
45
|
-
* Formats a raw Ethereum address
|
|
42
|
+
* Formats a raw Ethereum address into a Tempo address string.
|
|
46
43
|
*
|
|
47
44
|
* @example
|
|
48
45
|
* ```ts twoslash
|
|
49
46
|
* import { TempoAddress } from 'ox/tempo'
|
|
50
47
|
*
|
|
51
48
|
* const address = TempoAddress.format('0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28')
|
|
52
|
-
* // @log: '
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ### Zone Address
|
|
57
|
-
* ```ts twoslash
|
|
58
|
-
* import { TempoAddress } from 'ox/tempo'
|
|
59
|
-
*
|
|
60
|
-
* const address = TempoAddress.format(
|
|
61
|
-
* '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28',
|
|
62
|
-
* { zoneId: 1 },
|
|
63
|
-
* )
|
|
64
|
-
* // @log: 'tempoz1qqqhgtf4e3nrfszn9yj68wzyhj08t90jh55q74d9uj'
|
|
49
|
+
* // @log: 'tempox0x742d35cc6634c0532925a3b844bc9e7595f2bd28'
|
|
65
50
|
* ```
|
|
66
51
|
*
|
|
67
52
|
* @param address - The raw 20-byte Ethereum address.
|
|
68
|
-
* @param options - Options.
|
|
69
53
|
* @returns The encoded Tempo address string.
|
|
70
54
|
*/
|
|
71
|
-
export function format(address: Address
|
|
72
|
-
const { zoneId } = options
|
|
73
|
-
|
|
55
|
+
export function format(address: Address): Tempo {
|
|
74
56
|
const resolved = resolve(address)
|
|
75
|
-
|
|
76
|
-
const version = new Uint8Array([0x00])
|
|
77
|
-
const zone = zoneId != null ? CompactSize.toBytes(zoneId) : new Uint8Array()
|
|
78
|
-
const data = Bytes.concat(version, zone, Bytes.fromHex(resolved))
|
|
79
|
-
|
|
80
|
-
return Bech32m.encode(hrp, data) as Tempo
|
|
57
|
+
return `tempox${resolved.toLowerCase()}` as Tempo
|
|
81
58
|
}
|
|
82
59
|
|
|
83
60
|
export declare namespace format {
|
|
84
|
-
type Options = {
|
|
85
|
-
/** Zone ID for zone addresses. */
|
|
86
|
-
zoneId?: number | bigint | undefined
|
|
87
|
-
}
|
|
88
|
-
|
|
89
61
|
type ErrorType = Errors.GlobalErrorType
|
|
90
62
|
}
|
|
91
63
|
|
|
92
64
|
/**
|
|
93
|
-
* Parses a Tempo address string into a raw Ethereum address
|
|
65
|
+
* Parses a Tempo address string into a raw Ethereum address.
|
|
94
66
|
*
|
|
95
67
|
* @example
|
|
96
|
-
* ### Mainnet Address
|
|
97
68
|
* ```ts twoslash
|
|
98
69
|
* import { TempoAddress } from 'ox/tempo'
|
|
99
70
|
*
|
|
100
71
|
* const result = TempoAddress.parse(
|
|
101
|
-
* '
|
|
72
|
+
* 'tempox0x742d35cc6634c0532925a3b844bc9e7595f2bd28',
|
|
102
73
|
* )
|
|
103
|
-
* // @log: { address: '0x742d35CC6634c0532925a3B844bc9e7595F2Bd28'
|
|
104
|
-
* ```
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* ### Zone Address
|
|
108
|
-
* ```ts twoslash
|
|
109
|
-
* import { TempoAddress } from 'ox/tempo'
|
|
110
|
-
*
|
|
111
|
-
* const result = TempoAddress.parse(
|
|
112
|
-
* 'tempoz1qqqhgtf4e3nrfszn9yj68wzyhj08t90jh55q74d9uj',
|
|
113
|
-
* )
|
|
114
|
-
* // @log: { address: '0x742d35CC6634c0532925a3B844bc9e7595F2Bd28', zoneId: 1 }
|
|
74
|
+
* // @log: { address: '0x742d35CC6634c0532925a3B844bc9e7595F2Bd28' }
|
|
115
75
|
* ```
|
|
116
76
|
*
|
|
117
77
|
* @param tempoAddress - The Tempo address string to parse.
|
|
118
|
-
* @returns The parsed raw address
|
|
78
|
+
* @returns The parsed raw address.
|
|
119
79
|
*/
|
|
120
80
|
export function parse(tempoAddress: string): parse.ReturnType {
|
|
121
|
-
|
|
122
|
-
let data: Uint8Array
|
|
123
|
-
try {
|
|
124
|
-
const decoded = Bech32m.decode(tempoAddress)
|
|
125
|
-
hrp = decoded.hrp
|
|
126
|
-
data = decoded.data
|
|
127
|
-
} catch {
|
|
128
|
-
throw new InvalidChecksumError({ address: tempoAddress })
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (hrp !== 'tempo' && hrp !== 'tempoz')
|
|
81
|
+
if (!tempoAddress.startsWith('tempox'))
|
|
132
82
|
throw new InvalidPrefixError({ address: tempoAddress })
|
|
133
83
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
address: tempoAddress,
|
|
137
|
-
version: data.length > 0 ? data[0]! : undefined,
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
const payload = data.slice(1)
|
|
141
|
-
|
|
142
|
-
let zoneId: number | bigint | undefined
|
|
143
|
-
let rawAddress: Uint8Array
|
|
144
|
-
if (hrp === 'tempoz') {
|
|
145
|
-
const { value, size } = CompactSize.fromBytes(payload)
|
|
146
|
-
zoneId = value
|
|
147
|
-
rawAddress = payload.slice(size)
|
|
148
|
-
} else {
|
|
149
|
-
zoneId = undefined
|
|
150
|
-
rawAddress = payload
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (rawAddress.length !== 20)
|
|
154
|
-
throw new InvalidLengthError({
|
|
155
|
-
address: tempoAddress,
|
|
156
|
-
expected: 20,
|
|
157
|
-
actual: rawAddress.length,
|
|
158
|
-
})
|
|
84
|
+
const hex = tempoAddress.slice('tempox'.length)
|
|
85
|
+
Hex.assert(hex, { strict: true })
|
|
159
86
|
|
|
160
|
-
const address = core_Address.checksum(
|
|
87
|
+
const address = core_Address.checksum(hex)
|
|
161
88
|
|
|
162
|
-
return { address
|
|
89
|
+
return { address }
|
|
163
90
|
}
|
|
164
91
|
|
|
165
92
|
export declare namespace parse {
|
|
166
93
|
type ReturnType = {
|
|
167
94
|
/** The raw 20-byte Ethereum address. */
|
|
168
95
|
address: core_Address.Address
|
|
169
|
-
/** The zone ID, or `undefined` for mainnet addresses. */
|
|
170
|
-
zoneId: number | bigint | undefined
|
|
171
96
|
}
|
|
172
97
|
|
|
173
|
-
type ErrorType =
|
|
174
|
-
| InvalidPrefixError
|
|
175
|
-
| InvalidVersionError
|
|
176
|
-
| InvalidLengthError
|
|
177
|
-
| InvalidChecksumError
|
|
178
|
-
| Errors.GlobalErrorType
|
|
98
|
+
type ErrorType = InvalidPrefixError | Errors.GlobalErrorType
|
|
179
99
|
}
|
|
180
100
|
|
|
181
101
|
/**
|
|
@@ -186,7 +106,7 @@ export declare namespace parse {
|
|
|
186
106
|
* import { TempoAddress } from 'ox/tempo'
|
|
187
107
|
*
|
|
188
108
|
* const valid = TempoAddress.validate(
|
|
189
|
-
* '
|
|
109
|
+
* 'tempox0x742d35cc6634c0532925a3b844bc9e7595f2bd28',
|
|
190
110
|
* )
|
|
191
111
|
* // @log: true
|
|
192
112
|
* ```
|
|
@@ -209,45 +129,7 @@ export class InvalidPrefixError extends Errors.BaseError {
|
|
|
209
129
|
|
|
210
130
|
constructor({ address }: { address: string }) {
|
|
211
131
|
super(
|
|
212
|
-
`Tempo address "${address}" has an invalid prefix. Expected "
|
|
213
|
-
)
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/** Thrown when a Tempo address has an unsupported version byte. */
|
|
218
|
-
export class InvalidVersionError extends Errors.BaseError {
|
|
219
|
-
override readonly name = 'TempoAddress.InvalidVersionError'
|
|
220
|
-
|
|
221
|
-
constructor({
|
|
222
|
-
address,
|
|
223
|
-
version,
|
|
224
|
-
}: { address: string; version: number | undefined }) {
|
|
225
|
-
super(
|
|
226
|
-
`Tempo address "${address}" has unsupported version ${version === undefined ? '(missing)' : `0x${version.toString(16).padStart(2, '0')}`}. Only version 0x00 is supported.`,
|
|
132
|
+
`Tempo address "${address}" has an invalid prefix. Expected "tempox".`,
|
|
227
133
|
)
|
|
228
134
|
}
|
|
229
135
|
}
|
|
230
|
-
|
|
231
|
-
/** Thrown when a Tempo address has an invalid payload length. */
|
|
232
|
-
export class InvalidLengthError extends Errors.BaseError {
|
|
233
|
-
override readonly name = 'TempoAddress.InvalidLengthError'
|
|
234
|
-
|
|
235
|
-
constructor({
|
|
236
|
-
address,
|
|
237
|
-
expected,
|
|
238
|
-
actual,
|
|
239
|
-
}: { address: string; expected: number; actual: number }) {
|
|
240
|
-
super(
|
|
241
|
-
`Tempo address "${address}" has an invalid payload length. Expected ${expected} bytes, got ${actual}.`,
|
|
242
|
-
)
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/** Thrown when a Tempo address has an invalid checksum. */
|
|
247
|
-
export class InvalidChecksumError extends Errors.BaseError {
|
|
248
|
-
override readonly name = 'TempoAddress.InvalidChecksumError'
|
|
249
|
-
|
|
250
|
-
constructor({ address }: { address: string }) {
|
|
251
|
-
super(`Tempo address "${address}" has an invalid checksum.`)
|
|
252
|
-
}
|
|
253
|
-
}
|