walletpair-sdk 1.0.2 → 1.0.5
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/README.md +13 -0
- package/dist/ble/framing.d.ts.map +1 -1
- package/dist/ble/framing.js +2 -2
- package/dist/ble/framing.js.map +1 -1
- package/dist/ble/index.d.ts +2 -2
- package/dist/ble/index.d.ts.map +1 -1
- package/dist/ble/index.js +2 -2
- package/dist/ble/index.js.map +1 -1
- package/dist/ble/web-ble-transport.d.ts +1 -1
- package/dist/ble/web-ble-transport.d.ts.map +1 -1
- package/dist/ble/web-ble-transport.js +23 -12
- package/dist/ble/web-ble-transport.js.map +1 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +29 -12
- package/dist/crypto.js.map +1 -1
- package/dist/dapp-session.d.ts.map +1 -1
- package/dist/dapp-session.js +15 -5
- package/dist/dapp-session.js.map +1 -1
- package/dist/emitter.d.ts +1 -3
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +4 -2
- package/dist/emitter.js.map +1 -1
- package/dist/evm/eip1193.d.ts +2 -2
- package/dist/evm/eip1193.d.ts.map +1 -1
- package/dist/evm/eip1193.js +32 -18
- package/dist/evm/eip1193.js.map +1 -1
- package/dist/evm/index.d.ts +2 -2
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js.map +1 -1
- package/dist/wallet-session.d.ts.map +1 -1
- package/dist/wallet-session.js +4 -3
- package/dist/wallet-session.js.map +1 -1
- package/dist/ws-transport.d.ts +3 -2
- package/dist/ws-transport.d.ts.map +1 -1
- package/dist/ws-transport.js +13 -4
- package/dist/ws-transport.js.map +1 -1
- package/package.json +20 -1
- package/src/__tests__/adversarial/crypto-attacks.test.ts +240 -233
- package/src/__tests__/adversarial/malicious-dapp.test.ts +228 -194
- package/src/__tests__/adversarial/malicious-relay.test.ts +292 -220
- package/src/__tests__/adversarial/malicious-wallet.test.ts +246 -180
- package/src/__tests__/spec-compliance/canonical-json.test.ts +105 -105
- package/src/__tests__/spec-compliance/crypto-vectors.test.ts +149 -154
- package/src/__tests__/spec-compliance/message-format.test.ts +180 -151
- package/src/__tests__/spec-compliance/sequence-numbers.test.ts +142 -149
- package/src/__tests__/spec-compliance/state-machine.test.ts +203 -180
- package/src/ble/framing.test.ts +122 -114
- package/src/ble/framing.ts +48 -51
- package/src/ble/index.ts +7 -7
- package/src/ble/web-ble-transport.test.ts +93 -84
- package/src/ble/web-ble-transport.ts +70 -57
- package/src/ble/web-bluetooth.d.ts +19 -19
- package/src/canonical-json.test.ts +301 -285
- package/src/crypto-directional.test.ts +155 -129
- package/src/crypto-hardening.test.ts +292 -283
- package/src/crypto.test.ts +364 -346
- package/src/crypto.ts +185 -175
- package/src/dapp-session.test.ts +522 -385
- package/src/dapp-session.ts +17 -11
- package/src/emitter.test.ts +122 -122
- package/src/emitter.ts +20 -18
- package/src/evm/eip1193.test.ts +283 -205
- package/src/evm/eip1193.ts +162 -138
- package/src/evm/index.ts +5 -5
- package/src/evm/wagmi.test.ts +1 -1
- package/src/integration.test.ts +329 -201
- package/src/security.test.ts +331 -238
- package/src/sequence-validation.test.ts +6 -9
- package/src/test-helpers.ts +102 -78
- package/src/types.test.ts +45 -50
- package/src/wallet-session.test.ts +611 -383
- package/src/wallet-session.ts +7 -9
- package/src/ws-transport.test.ts +141 -139
- package/src/ws-transport.ts +52 -41
|
@@ -6,17 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
9
|
-
import type { AadHeader } from './crypto.js'
|
|
10
9
|
import {
|
|
11
10
|
b64urlDecode,
|
|
12
|
-
b64urlEncode,
|
|
13
11
|
buildPairingUri,
|
|
14
12
|
computeSharedSecret,
|
|
15
13
|
deriveSessionKey,
|
|
16
14
|
generateChannelId,
|
|
17
15
|
generateX25519KeyPair,
|
|
18
16
|
sealPayload,
|
|
19
|
-
unsealPayload,
|
|
20
17
|
} from './crypto.js'
|
|
21
18
|
import { DAppSession } from './dapp-session.js'
|
|
22
19
|
import { MockRelay, MockTransport, makeJoinBody, parseSnapshot } from './test-helpers.js'
|
|
@@ -71,7 +68,7 @@ interface ConnectedPair {
|
|
|
71
68
|
channelId: string
|
|
72
69
|
}
|
|
73
70
|
|
|
74
|
-
async function
|
|
71
|
+
async function _setupConnectedPair(): Promise<ConnectedPair> {
|
|
75
72
|
const dappTransport = new MockTransport()
|
|
76
73
|
const walletTransport = new MockTransport()
|
|
77
74
|
const _relay = new MockRelay(dappTransport, walletTransport)
|
|
@@ -110,7 +107,7 @@ async function setupConnectedPair(): Promise<ConnectedPair> {
|
|
|
110
107
|
// Instead, we extract from what the relay forwarded.
|
|
111
108
|
// The walletTransport.sent has the join message with from = wallet pubkey.
|
|
112
109
|
const walletJoinMsg = walletTransport.sent.find((m) => m.t === 'join')!
|
|
113
|
-
const
|
|
110
|
+
const _walletPubB64 = walletJoinMsg.from!
|
|
114
111
|
// The dappTransport.sent has the create message with from = dApp pubkey.
|
|
115
112
|
const dappCreateMsg = dappTransport.sent.find((m) => m.t === 'create')!
|
|
116
113
|
const dappPubB64 = dappCreateMsg.from!
|
|
@@ -159,12 +156,12 @@ async function connectDAppManually(ctx: ReturnType<typeof setupDAppWithManualWal
|
|
|
159
156
|
ch: session.channelId,
|
|
160
157
|
ts: Date.now(),
|
|
161
158
|
from: walletKp.publicKeyB64,
|
|
162
|
-
body: makeJoinBody(session.channelId, transport.sent[0]
|
|
159
|
+
body: makeJoinBody(session.channelId, transport.sent[0]?.from!, walletKp),
|
|
163
160
|
} as ProtocolMessage)
|
|
164
161
|
|
|
165
162
|
// Derive root key from wallet side. Responses/events use wallet->dApp key,
|
|
166
163
|
// which is DAppSession.recvKey after the join transcript is processed.
|
|
167
|
-
const dappPubB64 = transport.sent[0]
|
|
164
|
+
const dappPubB64 = transport.sent[0]?.from!
|
|
168
165
|
const dappPub = b64urlDecode(dappPubB64)
|
|
169
166
|
const shared = computeSharedSecret(walletKp.privateKey, dappPub)
|
|
170
167
|
deriveSessionKey(shared, session.channelId)
|
|
@@ -225,7 +222,7 @@ async function connectWalletManually(ctx: ReturnType<typeof setupWalletWithManua
|
|
|
225
222
|
|
|
226
223
|
// Derive root key from dApp side. Requests use dApp->wallet key,
|
|
227
224
|
// which is WalletSession.recvKey after prepareJoin().
|
|
228
|
-
const walletPubB64 = transport.sent.find((m) => m.t === 'join')
|
|
225
|
+
const walletPubB64 = transport.sent.find((m) => m.t === 'join')?.from!
|
|
229
226
|
const walletPub = b64urlDecode(walletPubB64)
|
|
230
227
|
const shared = computeSharedSecret(dappKp.privateKey, walletPub)
|
|
231
228
|
deriveSessionKey(shared, channelId)
|
|
@@ -1085,7 +1082,7 @@ describe('Sequence validation', () => {
|
|
|
1085
1082
|
ch: session.channelId,
|
|
1086
1083
|
ts: Date.now(),
|
|
1087
1084
|
from: walletKp.publicKeyB64,
|
|
1088
|
-
body: makeJoinBody(session.channelId, transport.sent[0]
|
|
1085
|
+
body: makeJoinBody(session.channelId, transport.sent[0]?.from!, walletKp),
|
|
1089
1086
|
} as ProtocolMessage)
|
|
1090
1087
|
|
|
1091
1088
|
// Session enters pending_accept briefly, then auto-accept sends accept
|
package/src/test-helpers.ts
CHANGED
|
@@ -2,29 +2,35 @@
|
|
|
2
2
|
* Shared test helpers — mock transport for unit testing sessions.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { X25519KeyPair } from './crypto.js'
|
|
6
6
|
import {
|
|
7
7
|
b64urlDecode,
|
|
8
8
|
computeSharedSecret,
|
|
9
9
|
deriveJoinEncryptionKey,
|
|
10
10
|
deriveSessionKey,
|
|
11
11
|
sealJoin,
|
|
12
|
-
} from './crypto.js'
|
|
13
|
-
import type {
|
|
12
|
+
} from './crypto.js'
|
|
13
|
+
import type {
|
|
14
|
+
Capabilities,
|
|
15
|
+
ProtocolMessage,
|
|
16
|
+
Transport,
|
|
17
|
+
TransportState,
|
|
18
|
+
WalletMeta,
|
|
19
|
+
} from './types.js'
|
|
14
20
|
|
|
15
21
|
export const DEFAULT_TEST_CAPABILITIES: Capabilities = {
|
|
16
22
|
methods: ['wallet_getAccounts', 'wallet_signMessage'],
|
|
17
23
|
events: ['accountsChanged', 'chainChanged'],
|
|
18
24
|
chains: ['eip155:1'],
|
|
19
|
-
}
|
|
25
|
+
}
|
|
20
26
|
|
|
21
27
|
/** Extract the JSON payload from a signed or unsigned snapshot string. */
|
|
22
28
|
export function parseSnapshot(signed: string): Record<string, unknown> {
|
|
23
29
|
// Signed format: "<64-hex-mac>.<json>"
|
|
24
30
|
if (signed.length > 65 && signed[64] === '.') {
|
|
25
|
-
return JSON.parse(signed.slice(65))
|
|
31
|
+
return JSON.parse(signed.slice(65))
|
|
26
32
|
}
|
|
27
|
-
return JSON.parse(signed)
|
|
33
|
+
return JSON.parse(signed)
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
export const DEFAULT_TEST_WALLET_META: WalletMeta = {
|
|
@@ -32,7 +38,7 @@ export const DEFAULT_TEST_WALLET_META: WalletMeta = {
|
|
|
32
38
|
description: 'Test wallet',
|
|
33
39
|
url: 'https://wallet.test',
|
|
34
40
|
icon: 'https://wallet.test/icon.png',
|
|
35
|
-
}
|
|
41
|
+
}
|
|
36
42
|
|
|
37
43
|
export function makeSealedJoin(
|
|
38
44
|
channelId: string,
|
|
@@ -41,15 +47,15 @@ export function makeSealedJoin(
|
|
|
41
47
|
capabilities: Capabilities = DEFAULT_TEST_CAPABILITIES,
|
|
42
48
|
meta: WalletMeta = DEFAULT_TEST_WALLET_META,
|
|
43
49
|
): string {
|
|
44
|
-
const dappPub = b64urlDecode(dappPubKeyB64)
|
|
45
|
-
const shared = computeSharedSecret(walletKp.privateKey, dappPub)
|
|
46
|
-
const rootKey = deriveSessionKey(shared, channelId)
|
|
47
|
-
const joinKey = deriveJoinEncryptionKey(rootKey, channelId)
|
|
48
|
-
const sealed = sealJoin(joinKey, channelId, capabilities, meta)
|
|
49
|
-
shared.fill(0)
|
|
50
|
-
rootKey.fill(0)
|
|
51
|
-
joinKey.fill(0)
|
|
52
|
-
return sealed
|
|
50
|
+
const dappPub = b64urlDecode(dappPubKeyB64)
|
|
51
|
+
const shared = computeSharedSecret(walletKp.privateKey, dappPub)
|
|
52
|
+
const rootKey = deriveSessionKey(shared, channelId)
|
|
53
|
+
const joinKey = deriveJoinEncryptionKey(rootKey, channelId)
|
|
54
|
+
const sealed = sealJoin(joinKey, channelId, capabilities, meta)
|
|
55
|
+
shared.fill(0)
|
|
56
|
+
rootKey.fill(0)
|
|
57
|
+
joinKey.fill(0)
|
|
58
|
+
return sealed
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
export function makeJoinBody(
|
|
@@ -61,7 +67,7 @@ export function makeJoinBody(
|
|
|
61
67
|
): { sealed_join: string } {
|
|
62
68
|
return {
|
|
63
69
|
sealed_join: makeSealedJoin(channelId, dappPubKeyB64, walletKp, capabilities, meta),
|
|
64
|
-
}
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
/**
|
|
@@ -69,47 +75,53 @@ export function makeJoinBody(
|
|
|
69
75
|
* to simulate a relay (messages sent on one arrive on the other).
|
|
70
76
|
*/
|
|
71
77
|
export class MockTransport implements Transport {
|
|
72
|
-
state: TransportState = 'disconnected'
|
|
73
|
-
sent: ProtocolMessage[] = []
|
|
78
|
+
state: TransportState = 'disconnected'
|
|
79
|
+
sent: ProtocolMessage[] = []
|
|
74
80
|
|
|
75
|
-
private messageHandler: ((msg: ProtocolMessage) => void) | null = null
|
|
76
|
-
private closeHandler: (() => void) | null = null
|
|
77
|
-
private openHandler: (() => void) | null = null
|
|
81
|
+
private messageHandler: ((msg: ProtocolMessage) => void) | null = null
|
|
82
|
+
private closeHandler: (() => void) | null = null
|
|
83
|
+
private openHandler: (() => void) | null = null
|
|
78
84
|
|
|
79
85
|
/** Link to the peer's transport. */
|
|
80
|
-
peer: MockTransport | null = null
|
|
86
|
+
peer: MockTransport | null = null
|
|
81
87
|
|
|
82
|
-
onMessage(handler: (msg: ProtocolMessage) => void): void {
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
onMessage(handler: (msg: ProtocolMessage) => void): void {
|
|
89
|
+
this.messageHandler = handler
|
|
90
|
+
}
|
|
91
|
+
onClose(handler: () => void): void {
|
|
92
|
+
this.closeHandler = handler
|
|
93
|
+
}
|
|
94
|
+
onOpen(handler: () => void): void {
|
|
95
|
+
this.openHandler = handler
|
|
96
|
+
}
|
|
85
97
|
|
|
86
98
|
async connect(): Promise<void> {
|
|
87
|
-
this.state = 'connected'
|
|
88
|
-
this.openHandler?.()
|
|
99
|
+
this.state = 'connected'
|
|
100
|
+
this.openHandler?.()
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
send(msg: ProtocolMessage): void {
|
|
92
|
-
this.sent.push(msg)
|
|
104
|
+
this.sent.push(msg)
|
|
93
105
|
// Deliver to peer asynchronously (simulates relay)
|
|
94
106
|
if (this.peer) {
|
|
95
|
-
const peer = this.peer
|
|
96
|
-
queueMicrotask(() => peer.receive(msg))
|
|
107
|
+
const peer = this.peer
|
|
108
|
+
queueMicrotask(() => peer.receive(msg))
|
|
97
109
|
}
|
|
98
110
|
}
|
|
99
111
|
|
|
100
112
|
disconnect(): void {
|
|
101
|
-
this.state = 'disconnected'
|
|
113
|
+
this.state = 'disconnected'
|
|
102
114
|
}
|
|
103
115
|
|
|
104
116
|
/** Simulate receiving a message from the relay. */
|
|
105
117
|
receive(msg: ProtocolMessage): void {
|
|
106
|
-
this.messageHandler?.(msg)
|
|
118
|
+
this.messageHandler?.(msg)
|
|
107
119
|
}
|
|
108
120
|
|
|
109
121
|
/** Simulate transport close (disconnect from relay). */
|
|
110
122
|
simulateClose(): void {
|
|
111
|
-
this.state = 'disconnected'
|
|
112
|
-
this.closeHandler?.()
|
|
123
|
+
this.state = 'disconnected'
|
|
124
|
+
this.closeHandler?.()
|
|
113
125
|
}
|
|
114
126
|
}
|
|
115
127
|
|
|
@@ -118,11 +130,11 @@ export class MockTransport implements Transport {
|
|
|
118
130
|
* Messages sent on dapp arrive on wallet and vice versa.
|
|
119
131
|
*/
|
|
120
132
|
export function createLinkedTransports(): { dapp: MockTransport; wallet: MockTransport } {
|
|
121
|
-
const dapp = new MockTransport()
|
|
122
|
-
const wallet = new MockTransport()
|
|
123
|
-
dapp.peer = wallet
|
|
124
|
-
wallet.peer = dapp
|
|
125
|
-
return { dapp, wallet }
|
|
133
|
+
const dapp = new MockTransport()
|
|
134
|
+
const wallet = new MockTransport()
|
|
135
|
+
dapp.peer = wallet
|
|
136
|
+
wallet.peer = dapp
|
|
137
|
+
return { dapp, wallet }
|
|
126
138
|
}
|
|
127
139
|
|
|
128
140
|
/**
|
|
@@ -131,62 +143,71 @@ export function createLinkedTransports(): { dapp: MockTransport; wallet: MockTra
|
|
|
131
143
|
* When dApp sends "accept", respond with "ready.connected" to both.
|
|
132
144
|
*/
|
|
133
145
|
export class MockRelay {
|
|
134
|
-
private dappTransport: MockTransport
|
|
135
|
-
private walletTransport: MockTransport
|
|
146
|
+
private dappTransport: MockTransport
|
|
147
|
+
private walletTransport: MockTransport
|
|
136
148
|
|
|
137
149
|
constructor(dapp: MockTransport, wallet: MockTransport) {
|
|
138
|
-
this.dappTransport = dapp
|
|
139
|
-
this.walletTransport = wallet
|
|
150
|
+
this.dappTransport = dapp
|
|
151
|
+
this.walletTransport = wallet
|
|
140
152
|
|
|
141
153
|
// Intercept sends and inject relay behavior
|
|
142
|
-
const origDappSend = dapp.send.bind(dapp)
|
|
154
|
+
const origDappSend = dapp.send.bind(dapp)
|
|
143
155
|
dapp.send = (msg: ProtocolMessage) => {
|
|
144
|
-
origDappSend(msg)
|
|
145
|
-
this.handleDappMessage(msg)
|
|
146
|
-
}
|
|
156
|
+
origDappSend(msg)
|
|
157
|
+
this.handleDappMessage(msg)
|
|
158
|
+
}
|
|
147
159
|
|
|
148
|
-
const origWalletSend = wallet.send.bind(wallet)
|
|
160
|
+
const origWalletSend = wallet.send.bind(wallet)
|
|
149
161
|
wallet.send = (msg: ProtocolMessage) => {
|
|
150
|
-
origWalletSend(msg)
|
|
151
|
-
this.handleWalletMessage(msg)
|
|
152
|
-
}
|
|
162
|
+
origWalletSend(msg)
|
|
163
|
+
this.handleWalletMessage(msg)
|
|
164
|
+
}
|
|
153
165
|
|
|
154
166
|
// Don't forward to peer directly — relay controls message flow
|
|
155
|
-
dapp.peer = null
|
|
156
|
-
wallet.peer = null
|
|
167
|
+
dapp.peer = null
|
|
168
|
+
wallet.peer = null
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
private handleDappMessage(msg: ProtocolMessage): void {
|
|
160
172
|
if (msg.t === 'create') {
|
|
161
173
|
queueMicrotask(() => {
|
|
162
174
|
this.dappTransport.receive({
|
|
163
|
-
v: 1,
|
|
164
|
-
|
|
175
|
+
v: 1,
|
|
176
|
+
t: 'ready',
|
|
177
|
+
ch: msg.ch,
|
|
178
|
+
ts: Date.now(),
|
|
179
|
+
from: '_adapter',
|
|
165
180
|
body: { state: 'waiting', reconnect: false, remote: null },
|
|
166
|
-
} as ProtocolMessage)
|
|
167
|
-
})
|
|
181
|
+
} as ProtocolMessage)
|
|
182
|
+
})
|
|
168
183
|
} else if (msg.t === 'accept') {
|
|
169
184
|
queueMicrotask(() => {
|
|
170
|
-
const target = (msg.body as any).target
|
|
185
|
+
const target = (msg.body as any).target
|
|
171
186
|
this.dappTransport.receive({
|
|
172
|
-
v: 1,
|
|
173
|
-
|
|
187
|
+
v: 1,
|
|
188
|
+
t: 'ready',
|
|
189
|
+
ch: msg.ch,
|
|
190
|
+
ts: Date.now(),
|
|
191
|
+
from: '_adapter',
|
|
174
192
|
body: { state: 'connected', reconnect: false, remote: target },
|
|
175
|
-
} as ProtocolMessage)
|
|
193
|
+
} as ProtocolMessage)
|
|
176
194
|
this.walletTransport.receive({
|
|
177
|
-
v: 1,
|
|
178
|
-
|
|
195
|
+
v: 1,
|
|
196
|
+
t: 'ready',
|
|
197
|
+
ch: msg.ch,
|
|
198
|
+
ts: Date.now(),
|
|
199
|
+
from: '_adapter',
|
|
179
200
|
body: { state: 'connected', reconnect: false, remote: msg.from },
|
|
180
|
-
} as ProtocolMessage)
|
|
181
|
-
})
|
|
201
|
+
} as ProtocolMessage)
|
|
202
|
+
})
|
|
182
203
|
} else if (msg.t === 'req') {
|
|
183
204
|
// Forward to wallet
|
|
184
|
-
queueMicrotask(() => this.walletTransport.receive(msg))
|
|
205
|
+
queueMicrotask(() => this.walletTransport.receive(msg))
|
|
185
206
|
} else if (msg.t === 'ping') {
|
|
186
207
|
// Forward to wallet
|
|
187
|
-
queueMicrotask(() => this.walletTransport.receive(msg))
|
|
208
|
+
queueMicrotask(() => this.walletTransport.receive(msg))
|
|
188
209
|
} else if (msg.t === 'close') {
|
|
189
|
-
queueMicrotask(() => this.walletTransport.receive(msg))
|
|
210
|
+
queueMicrotask(() => this.walletTransport.receive(msg))
|
|
190
211
|
}
|
|
191
212
|
}
|
|
192
213
|
|
|
@@ -195,22 +216,25 @@ export class MockRelay {
|
|
|
195
216
|
queueMicrotask(() => {
|
|
196
217
|
// Relay sends ready.waiting to wallet
|
|
197
218
|
this.walletTransport.receive({
|
|
198
|
-
v: 1,
|
|
199
|
-
|
|
219
|
+
v: 1,
|
|
220
|
+
t: 'ready',
|
|
221
|
+
ch: msg.ch,
|
|
222
|
+
ts: Date.now(),
|
|
223
|
+
from: '_adapter',
|
|
200
224
|
body: { state: 'waiting', reconnect: false, remote: null },
|
|
201
|
-
} as ProtocolMessage)
|
|
225
|
+
} as ProtocolMessage)
|
|
202
226
|
// Relay forwards join to dApp
|
|
203
|
-
this.dappTransport.receive(msg)
|
|
204
|
-
})
|
|
227
|
+
this.dappTransport.receive(msg)
|
|
228
|
+
})
|
|
205
229
|
} else if (msg.t === 'res') {
|
|
206
230
|
// Forward to dApp
|
|
207
|
-
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
231
|
+
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
208
232
|
} else if (msg.t === 'evt') {
|
|
209
|
-
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
233
|
+
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
210
234
|
} else if (msg.t === 'pong') {
|
|
211
|
-
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
235
|
+
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
212
236
|
} else if (msg.t === 'close') {
|
|
213
|
-
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
237
|
+
queueMicrotask(() => this.dappTransport.receive(msg))
|
|
214
238
|
}
|
|
215
239
|
}
|
|
216
240
|
}
|
package/src/types.test.ts
CHANGED
|
@@ -1,82 +1,77 @@
|
|
|
1
|
-
import { describe,
|
|
2
|
-
import {
|
|
3
|
-
parseChainId,
|
|
4
|
-
formatChainId,
|
|
5
|
-
evmChainId,
|
|
6
|
-
evmNumericChainId,
|
|
7
|
-
} from './types.js';
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { evmChainId, evmNumericChainId, formatChainId, parseChainId } from './types.js'
|
|
8
3
|
|
|
9
4
|
describe('parseChainId', () => {
|
|
10
5
|
it('parses eip155:1', () => {
|
|
11
|
-
const { namespace, reference } = parseChainId('eip155:1')
|
|
12
|
-
expect(namespace).toBe('eip155')
|
|
13
|
-
expect(reference).toBe('1')
|
|
14
|
-
})
|
|
6
|
+
const { namespace, reference } = parseChainId('eip155:1')
|
|
7
|
+
expect(namespace).toBe('eip155')
|
|
8
|
+
expect(reference).toBe('1')
|
|
9
|
+
})
|
|
15
10
|
|
|
16
11
|
it('parses solana:mainnet', () => {
|
|
17
|
-
const { namespace, reference } = parseChainId('solana:mainnet')
|
|
18
|
-
expect(namespace).toBe('solana')
|
|
19
|
-
expect(reference).toBe('mainnet')
|
|
20
|
-
})
|
|
12
|
+
const { namespace, reference } = parseChainId('solana:mainnet')
|
|
13
|
+
expect(namespace).toBe('solana')
|
|
14
|
+
expect(reference).toBe('mainnet')
|
|
15
|
+
})
|
|
21
16
|
|
|
22
17
|
it('parses cosmos:cosmoshub-4', () => {
|
|
23
|
-
const { namespace, reference } = parseChainId('cosmos:cosmoshub-4')
|
|
24
|
-
expect(namespace).toBe('cosmos')
|
|
25
|
-
expect(reference).toBe('cosmoshub-4')
|
|
26
|
-
})
|
|
18
|
+
const { namespace, reference } = parseChainId('cosmos:cosmoshub-4')
|
|
19
|
+
expect(namespace).toBe('cosmos')
|
|
20
|
+
expect(reference).toBe('cosmoshub-4')
|
|
21
|
+
})
|
|
27
22
|
|
|
28
23
|
it('throws on missing reference', () => {
|
|
29
|
-
expect(() => parseChainId('eip155')).toThrow('Invalid CAIP-2')
|
|
30
|
-
})
|
|
24
|
+
expect(() => parseChainId('eip155')).toThrow('Invalid CAIP-2')
|
|
25
|
+
})
|
|
31
26
|
|
|
32
27
|
it('throws on empty string', () => {
|
|
33
|
-
expect(() => parseChainId('')).toThrow('Invalid CAIP-2')
|
|
34
|
-
})
|
|
28
|
+
expect(() => parseChainId('')).toThrow('Invalid CAIP-2')
|
|
29
|
+
})
|
|
35
30
|
|
|
36
31
|
it('throws on just a colon', () => {
|
|
37
|
-
expect(() => parseChainId(':')).toThrow('Invalid CAIP-2')
|
|
38
|
-
})
|
|
39
|
-
})
|
|
32
|
+
expect(() => parseChainId(':')).toThrow('Invalid CAIP-2')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
40
35
|
|
|
41
36
|
describe('formatChainId', () => {
|
|
42
37
|
it('formats eip155 + 1', () => {
|
|
43
|
-
expect(formatChainId('eip155', '1')).toBe('eip155:1')
|
|
44
|
-
})
|
|
38
|
+
expect(formatChainId('eip155', '1')).toBe('eip155:1')
|
|
39
|
+
})
|
|
45
40
|
|
|
46
41
|
it('formats solana + mainnet', () => {
|
|
47
|
-
expect(formatChainId('solana', 'mainnet')).toBe('solana:mainnet')
|
|
48
|
-
})
|
|
42
|
+
expect(formatChainId('solana', 'mainnet')).toBe('solana:mainnet')
|
|
43
|
+
})
|
|
49
44
|
|
|
50
45
|
it('round-trips with parseChainId', () => {
|
|
51
|
-
const caip2 = 'eip155:137'
|
|
52
|
-
const { namespace, reference } = parseChainId(caip2)
|
|
53
|
-
expect(formatChainId(namespace, reference)).toBe(caip2)
|
|
54
|
-
})
|
|
55
|
-
})
|
|
46
|
+
const caip2 = 'eip155:137'
|
|
47
|
+
const { namespace, reference } = parseChainId(caip2)
|
|
48
|
+
expect(formatChainId(namespace, reference)).toBe(caip2)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
56
51
|
|
|
57
52
|
describe('evmChainId', () => {
|
|
58
53
|
it('converts numeric chain ID to CAIP-2', () => {
|
|
59
|
-
expect(evmChainId(1)).toBe('eip155:1')
|
|
60
|
-
expect(evmChainId(137)).toBe('eip155:137')
|
|
61
|
-
expect(evmChainId(42161)).toBe('eip155:42161')
|
|
62
|
-
})
|
|
63
|
-
})
|
|
54
|
+
expect(evmChainId(1)).toBe('eip155:1')
|
|
55
|
+
expect(evmChainId(137)).toBe('eip155:137')
|
|
56
|
+
expect(evmChainId(42161)).toBe('eip155:42161')
|
|
57
|
+
})
|
|
58
|
+
})
|
|
64
59
|
|
|
65
60
|
describe('evmNumericChainId', () => {
|
|
66
61
|
it('extracts numeric ID from eip155: prefix', () => {
|
|
67
|
-
expect(evmNumericChainId('eip155:1')).toBe(1)
|
|
68
|
-
expect(evmNumericChainId('eip155:137')).toBe(137)
|
|
69
|
-
expect(evmNumericChainId('eip155:42161')).toBe(42161)
|
|
70
|
-
})
|
|
62
|
+
expect(evmNumericChainId('eip155:1')).toBe(1)
|
|
63
|
+
expect(evmNumericChainId('eip155:137')).toBe(137)
|
|
64
|
+
expect(evmNumericChainId('eip155:42161')).toBe(42161)
|
|
65
|
+
})
|
|
71
66
|
|
|
72
67
|
it('returns null for non-eip155 chains', () => {
|
|
73
|
-
expect(evmNumericChainId('solana:mainnet')).toBeNull()
|
|
74
|
-
expect(evmNumericChainId('cosmos:cosmoshub-4')).toBeNull()
|
|
75
|
-
})
|
|
68
|
+
expect(evmNumericChainId('solana:mainnet')).toBeNull()
|
|
69
|
+
expect(evmNumericChainId('cosmos:cosmoshub-4')).toBeNull()
|
|
70
|
+
})
|
|
76
71
|
|
|
77
72
|
it('round-trips with evmChainId', () => {
|
|
78
73
|
for (const id of [1, 5, 10, 56, 137, 42161]) {
|
|
79
|
-
expect(evmNumericChainId(evmChainId(id))).toBe(id)
|
|
74
|
+
expect(evmNumericChainId(evmChainId(id))).toBe(id)
|
|
80
75
|
}
|
|
81
|
-
})
|
|
82
|
-
})
|
|
76
|
+
})
|
|
77
|
+
})
|