Skip to content

Commit 7021e98

Browse files
committed
feat(sdk): make the unsuffixed client name the v1 surface
1 parent 5ca8f12 commit 7021e98

13 files changed

Lines changed: 470 additions & 371 deletions

sdk/js/README.md

Lines changed: 158 additions & 138 deletions
Large diffs are not rendered by default.

sdk/js/src/__tests__/index-v1.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@
55
import { expect, describe, it } from 'vitest'
66
import http from 'http'
77
import type { AddressInfo } from 'net'
8-
import { DstackClientV0, DstackClientV1 } from '../index'
8+
import { DstackClient, DstackClientV0, DstackClientV1 } from '../index'
99
import type { GpuEvidenceBundleV1 } from '../index'
1010

1111
describe('DstackClientV1', () => {
12+
it('should be what the unsuffixed DstackClient names, as value and as type', () => {
13+
expect(DstackClient).toBe(DstackClientV1)
14+
// Typed as the alias, constructed through the alias: this line fails to
15+
// compile if either half of the export stops pointing at v1.
16+
const client: DstackClient = new DstackClient()
17+
expect(client).toBeInstanceOf(DstackClientV1)
18+
expect(client).not.toBeInstanceOf(DstackClientV0)
19+
})
20+
1221
it('should be able to get version', async () => {
1322
const client = new DstackClientV1()
1423
const result = await client.version()

sdk/js/src/__tests__/index.test.ts

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44

55
import { expect, describe, it, vi } from 'vitest'
66
import crypto from 'crypto' // Added for prehashed test
7-
import { DstackClient, DstackClientV0, TappdClient } from '../index'
7+
import { DstackClient, DstackClientV0, DstackClientV1, TappdClient } from '../index'
88

99
describe('DstackClientV0', () => {
10-
it('should keep DstackClient as an alias of DstackClientV0', () => {
11-
expect(DstackClient).toBe(DstackClientV0)
12-
expect(new DstackClient()).toBeInstanceOf(DstackClientV0)
10+
it('should only be reachable under its explicit name now', () => {
11+
expect(DstackClient).not.toBe(DstackClientV0)
12+
expect(new DstackClient()).not.toBeInstanceOf(DstackClientV0)
13+
})
14+
15+
it('should stay the base of TappdClient even though the alias moved to v1', () => {
16+
expect(new TappdClient()).toBeInstanceOf(DstackClientV0)
17+
expect(new TappdClient()).not.toBeInstanceOf(DstackClientV1)
1318
})
1419

1520
it('should able to derive key in TappdClient', async () => {
@@ -19,20 +24,20 @@ describe('DstackClientV0', () => {
1924
expect(result).toHaveProperty('certificate_chain')
2025
})
2126

22-
it('should throws error in DstackClient', async () => {
23-
const client = new DstackClient()
27+
it('should throws error in DstackClientV0', async () => {
28+
const client = new DstackClientV0()
2429
await expect(() => client.deriveKey('/', 'test')).rejects.toThrow('deriveKey is deprecated, please use getKey instead.')
2530
})
2631

2732
it('should able to get key', async () => {
28-
const client = new DstackClient()
33+
const client = new DstackClientV0()
2934
const result = await client.getKey('/', 'test')
3035
expect(result).toHaveProperty('key')
3136
expect(result).toHaveProperty('signature_chain')
3237
})
3338

3439
it('should able to get key with different algorithms', async () => {
35-
const client = new DstackClient()
40+
const client = new DstackClientV0()
3641
const resultSecp = await client.getKey('/secp', 'test', 'secp256k1')
3742
expect(resultSecp.key).toBeInstanceOf(Uint8Array)
3843
expect(resultSecp.key.length).toBe(32) // secp256k1 private key size
@@ -44,7 +49,7 @@ describe('DstackClientV0', () => {
4449

4550

4651
it('should able to request tdx quote', async () => {
47-
const client = new DstackClient()
52+
const client = new DstackClientV0()
4853
// You can put computation result as report data to tdxQuote. NOTE: it should serializable by JSON.stringify
4954
const result = await client.getQuote('some data or anything can be call by toJSON')
5055
expect(result).toHaveProperty('quote')
@@ -54,26 +59,26 @@ describe('DstackClientV0', () => {
5459
})
5560

5661
it('should be able to attest', async () => {
57-
const client = new DstackClient()
62+
const client = new DstackClientV0()
5863
const result = await client.attest('test')
5964
expect(result).toHaveProperty('attestation')
6065
expect(result.attestation).not.toBe('')
6166
})
6267

6368
it('should not carry the GPU methods, which this surface never served', () => {
64-
const client = new DstackClient() as any
69+
const client = new DstackClientV0() as any
6570
expect(client.attestGpu).toBeUndefined()
6671
expect(client.gpuInfo).toBeUndefined()
6772
})
6873

6974
it('should able to get derive key result as uint8array', async () => {
70-
const client = new DstackClient()
75+
const client = new DstackClientV0()
7176
const result = await client.getKey('/', 'test')
7277
expect(result.key).toBeInstanceOf(Uint8Array)
7378
})
7479

7580
it('should able to get derive key result as uint8array with specified length', async () => {
76-
const client = new DstackClient()
81+
const client = new DstackClientV0()
7782
const result = await client.getTlsKey()
7883
const full = result.asUint8Array()
7984
const key = result.asUint8Array(32)
@@ -84,33 +89,33 @@ describe('DstackClientV0', () => {
8489
})
8590

8691
it('should be able to get quote', async () => {
87-
const client = new DstackClient()
92+
const client = new DstackClientV0()
8893
const result = await client.getQuote('pure string')
8994
})
9095

9196
it('should throw error on report_data large then 64 characters', async () => {
92-
const client = new DstackClient()
97+
const client = new DstackClientV0()
9398
await expect(() => client.getQuote('0'.padEnd(65, 'x'))).rejects.toThrow()
9499
})
95100

96101
it('should throw error on report_data large then 64 bytes', async () => {
97-
const client = new DstackClient()
102+
const client = new DstackClientV0()
98103
await expect(() => client.getQuote(Buffer.alloc(65))).rejects.toThrow()
99104
})
100105

101106
it('should throw error on report_data large then 128 bytes', async () => {
102-
const client = new DstackClient()
107+
const client = new DstackClientV0()
103108
const input = new Uint8Array(65).fill(0)
104109
await expect(() => client.getQuote(input)).rejects.toThrow()
105110
})
106111

107112
it('should throw error on attest report_data larger than 64 bytes', async () => {
108-
const client = new DstackClient()
113+
const client = new DstackClientV0()
109114
await expect(() => client.attest(Buffer.alloc(65))).rejects.toThrow()
110115
})
111116

112117
it('should be able to get info', async () => {
113-
const client = new DstackClient()
118+
const client = new DstackClientV0()
114119
const result = await client.info()
115120
expect(result).toHaveProperty('app_id')
116121
expect(result).toHaveProperty('instance_id')
@@ -126,7 +131,7 @@ describe('DstackClientV0', () => {
126131
})
127132

128133
it('should be able to decode tcb info', async () => {
129-
const client = new DstackClient()
134+
const client = new DstackClientV0()
130135
const result = await client.info()
131136
const tcbInfo = result.tcb_info
132137
expect(tcbInfo).toHaveProperty('rtmr0')
@@ -142,7 +147,7 @@ describe('DstackClientV0', () => {
142147
})
143148

144149
it('should be able to get TLS key with alt names', async () => {
145-
const client = new DstackClient()
150+
const client = new DstackClientV0()
146151
const altNames = ['localhost', '127.0.0.1']
147152
const result = await client.getTlsKey({
148153
subject: 'test-subject',
@@ -162,7 +167,7 @@ describe('DstackClientV0', () => {
162167
const savedEnv = process.env.DSTACK_SIMULATOR_ENDPOINT
163168
delete process.env.DSTACK_SIMULATOR_ENDPOINT
164169

165-
expect(() => new DstackClient('/non/existent/socket')).toThrow('Unix socket file /non/existent/socket does not exist')
170+
expect(() => new DstackClientV0('/non/existent/socket')).toThrow('Unix socket file /non/existent/socket does not exist')
166171

167172
// Restore environment variable
168173
if (savedEnv) {
@@ -175,8 +180,8 @@ describe('DstackClientV0', () => {
175180
const savedEnv = process.env.DSTACK_SIMULATOR_ENDPOINT
176181
delete process.env.DSTACK_SIMULATOR_ENDPOINT
177182

178-
expect(() => new DstackClient('http://localhost:8080')).not.toThrow()
179-
expect(() => new DstackClient('https://example.com')).not.toThrow()
183+
expect(() => new DstackClientV0('http://localhost:8080')).not.toThrow()
184+
expect(() => new DstackClientV0('https://example.com')).not.toThrow()
180185

181186
// Restore environment variable
182187
if (savedEnv) {
@@ -185,13 +190,13 @@ describe('DstackClientV0', () => {
185190
})
186191

187192
it('should be able to check if service is reachable', async () => {
188-
const client = new DstackClient()
193+
const client = new DstackClientV0()
189194
const isReachable = await client.isReachable()
190195
expect(typeof isReachable).toBe('boolean')
191196
})
192197

193198
describe('Sign and Verify Methods', () => {
194-
const client = new DstackClient()
199+
const client = new DstackClientV0()
195200
const testData = 'Test message for signing'
196201
const badData = 'This is not the original message'
197202

@@ -261,12 +266,12 @@ describe('DstackClientV0', () => {
261266

262267
describe('emitEvent', () => {
263268
it('should reject an empty event name before reaching the agent', async () => {
264-
const client = new DstackClient()
269+
const client = new DstackClientV0()
265270
await expect(() => client.emitEvent('', 'payload')).rejects.toThrow('Event name cannot be empty')
266271
})
267272

268273
it('should surface the agent removal message instead of resolving silently', async () => {
269-
const client = new DstackClient()
274+
const client = new DstackClientV0()
270275
// The 0.6.0 agent always fails this. A caller that gets a resolved promise
271276
// would believe the event was measured, which is the one wrong answer here.
272277
await expect(() => client.emitEvent('test-event', 'payload')).rejects.toThrow(
@@ -276,21 +281,21 @@ describe('DstackClientV0', () => {
276281
})
277282

278283
it('should be able to get version', async () => {
279-
const client = new DstackClient()
284+
const client = new DstackClientV0()
280285
const result = await client.version()
281286
expect(result).toHaveProperty('version')
282287
expect(result.version).not.toBe('')
283288
})
284289

285290
it('should get key with k256 alias producing same result as secp256k1', async () => {
286-
const client = new DstackClient()
291+
const client = new DstackClientV0()
287292
const resultK256 = await client.getKey('/test', 'purpose', 'k256')
288293
const resultSecp = await client.getKey('/test', 'purpose', 'secp256k1')
289294
expect(resultK256.key).toEqual(resultSecp.key)
290295
})
291296

292297
it('should reject secp256k1_prehashed in getKey', async () => {
293-
const client = new DstackClient()
298+
const client = new DstackClientV0()
294299
await expect(() => client.getKey('/test', 'purpose', 'secp256k1_prehashed')).rejects.toThrow()
295300
})
296301

@@ -332,9 +337,9 @@ describe('DstackClientV0', () => {
332337
})
333338
})
334339

335-
describe('deprecated methods with DstackClient', () => {
340+
describe('deprecated methods with DstackClientV0', () => {
336341
it('should throws error in deriveKey method', async () => {
337-
const client = new DstackClient()
342+
const client = new DstackClientV0()
338343
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
339344

340345
await expect(() => client.deriveKey('/', 'test')).rejects.toThrow('deriveKey is deprecated, please use getKey instead.')
@@ -343,7 +348,7 @@ describe('DstackClientV0', () => {
343348
})
344349

345350
it('should throws error in tdxQuote method without hash algorithm parameter', async () => {
346-
const client = new DstackClient()
351+
const client = new DstackClientV0()
347352
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
348353

349354
await expect(() => client.tdxQuote('test data')).rejects.toThrow('tdxQuote only supports raw hash algorithm.')
@@ -352,7 +357,7 @@ describe('DstackClientV0', () => {
352357
})
353358

354359
it("should throws error in tdxQuote method with hash algorithm parameter other than raw", async () => {
355-
const client = new DstackClient()
360+
const client = new DstackClientV0()
356361
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
357362

358363
await expect(() => client.tdxQuote('test data', 'sha256')).rejects.toThrow('tdxQuote only supports raw hash algorithm.')
@@ -361,7 +366,7 @@ describe('DstackClientV0', () => {
361366
})
362367

363368
it('should able to get quote with plain report_data in tdxQuote method with warning', async () => {
364-
const client = new DstackClient()
369+
const client = new DstackClientV0()
365370
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
366371

367372
const result = await client.tdxQuote('test data', "raw")
@@ -373,7 +378,7 @@ describe('DstackClientV0', () => {
373378
})
374379

375380
it('should throws error in tdxQuote with hash algorithm parameter', async () => {
376-
const client = new DstackClient()
381+
const client = new DstackClientV0()
377382
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
378383

379384
await expect(() => client.tdxQuote('test data', 'sha256')).rejects.toThrow('tdxQuote only supports raw hash algorithm.')

sdk/js/src/__tests__/solana.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
import { expect, describe, it, vi } from 'vitest'
77
import { Keypair } from '@solana/web3.js'
88

9-
import { DstackClient, TappdClient } from '../index'
9+
import { DstackClientV0, TappdClient } from '../index'
1010
import { toKeypair, toKeypairSecure } from '../solana'
1111

1212
describe('solana support', () => {
1313
describe('toKeypair (legacy)', () => {
14-
it('should able to get keypair from getKey with DstackClient', async () => {
15-
const client = new DstackClient()
14+
it('should able to get keypair from getKey with DstackClientV0', async () => {
15+
const client = new DstackClientV0()
1616
const result = await client.getKey('/', 'test')
1717
const keypair = toKeypair(result)
1818
expect(keypair).toBeInstanceOf(Keypair)
@@ -32,8 +32,8 @@ describe('solana support', () => {
3232
consoleSpy.mockRestore()
3333
})
3434

35-
it('should able to get keypair from getTlsKey with DstackClient', async () => {
36-
const client = new DstackClient()
35+
it('should able to get keypair from getTlsKey with DstackClientV0', async () => {
36+
const client = new DstackClientV0()
3737
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
3838

3939
const result = await client.getTlsKey()
@@ -47,8 +47,8 @@ describe('solana support', () => {
4747
})
4848

4949
describe('toKeypairSecure', () => {
50-
it('should able to get keypair from getKey with DstackClient', async () => {
51-
const client = new DstackClient()
50+
it('should able to get keypair from getKey with DstackClientV0', async () => {
51+
const client = new DstackClientV0()
5252
const result = await client.getKey('/', 'test')
5353
const keypair = toKeypairSecure(result)
5454
expect(keypair).toBeInstanceOf(Keypair)
@@ -68,8 +68,8 @@ describe('solana support', () => {
6868
consoleSpy.mockRestore()
6969
})
7070

71-
it('should able to get keypair from getTlsKey with DstackClient', async () => {
72-
const client = new DstackClient()
71+
it('should able to get keypair from getTlsKey with DstackClientV0', async () => {
72+
const client = new DstackClientV0()
7373
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
7474

7575
const result = await client.getTlsKey()

sdk/js/src/__tests__/viem.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55

66
import { expect, describe, it, vi } from 'vitest'
7-
import { DstackClient, TappdClient } from '../index'
7+
import { DstackClientV0, TappdClient } from '../index'
88
import { toViemAccount, toViemAccountSecure } from '../viem'
99

1010
describe('viem support', () => {
1111
describe('toViemAccount (legacy)', () => {
12-
it('should able to get account from getKey with DstackClient', async () => {
13-
const client = new DstackClient()
12+
it('should able to get account from getKey with DstackClientV0', async () => {
13+
const client = new DstackClientV0()
1414
const result = await client.getKey('/', 'test')
1515
const account = toViemAccount(result)
1616

@@ -34,8 +34,8 @@ describe('viem support', () => {
3434
consoleSpy.mockRestore()
3535
})
3636

37-
it('should able to get account from getTlsKey with DstackClient', async () => {
38-
const client = new DstackClient()
37+
it('should able to get account from getTlsKey with DstackClientV0', async () => {
38+
const client = new DstackClientV0()
3939
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
4040

4141
const result = await client.getTlsKey()
@@ -51,8 +51,8 @@ describe('viem support', () => {
5151
})
5252

5353
describe('toViemAccountSecure', () => {
54-
it('should able to get account from getKey with DstackClient', async () => {
55-
const client = new DstackClient()
54+
it('should able to get account from getKey with DstackClientV0', async () => {
55+
const client = new DstackClientV0()
5656
const result = await client.getKey('/', 'test')
5757
const account = toViemAccountSecure(result)
5858

@@ -76,8 +76,8 @@ describe('viem support', () => {
7676
consoleSpy.mockRestore()
7777
})
7878

79-
it('should able to get account from getTlsKey with DstackClient', async () => {
80-
const client = new DstackClient()
79+
it('should able to get account from getTlsKey with DstackClientV0', async () => {
80+
const client = new DstackClientV0()
8181
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
8282

8383
const result = await client.getTlsKey()

0 commit comments

Comments
 (0)