Skip to content

Commit 469d339

Browse files
committed
refactor: migrate wallet wasm into sdk
1 parent 5441e7d commit 469d339

File tree

14 files changed

+366
-375
lines changed

14 files changed

+366
-375
lines changed

.github/actions/setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ runs:
2424
registry-url: https://registry.npmjs.org
2525
- uses: actions/setup-go@v4
2626
with:
27-
go-version: '1.20'
27+
go-version: '1.21.7'
2828
- uses: acifani/setup-tinygo@v2
2929
with:
3030
tinygo-version: '0.30.0'

go.work

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
go 1.20
1+
go 1.21.7
22

33
use (
44
./
55
./hostd
66
./renterd
7-
./walletd
87
./sdk
8+
./walletd
99
)

go.work.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
2+
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
3+
go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M=
14
go.sia.tech/mux v1.2.0/go.mod h1:Yyo6wZelOYTyvrHmJZ6aQfRoer3o4xyKQ4NmQLJrBSo=
5+
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
6+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
7+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

libs/sdk/src/rhp.spec.ts

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
2+
import {
3+
HostPrices,
4+
HostSettings,
5+
RPCReadSectorRequest,
6+
RPCReadSectorResponse,
7+
RPCSettingsResponse,
8+
RPCWriteSectorRequest,
9+
RPCWriteSectorResponse,
10+
} from './types'
11+
import { initSDKTest } from './initTest'
12+
13+
describe('rhp', () => {
14+
describe('generateAccount', () => {
15+
it('works', async () => {
16+
const sdk = await initSDKTest()
17+
const { privateKey, account, error } = sdk.rhp.generateAccount()
18+
expect(error).toBeUndefined()
19+
expect(privateKey).toBeDefined()
20+
expect(privateKey?.length).toBeGreaterThan(40)
21+
expect(account).toBeDefined()
22+
expect(account?.length).toBeGreaterThan(40)
23+
})
24+
})
25+
describe('settings', () => {
26+
describe('request', () => {
27+
it('valid', async () => {
28+
const sdk = await initSDKTest()
29+
const encode = sdk.rhp.encodeSettingsRequest()
30+
expect(encode.rpc).toBeDefined()
31+
expect(encode.error).not.toBeDefined()
32+
const decode = sdk.rhp.decodeSettingsRequest(encode.rpc!)
33+
expect(decode.data).toEqual({})
34+
expect(decode.error).toBeUndefined()
35+
})
36+
})
37+
describe('response', () => {
38+
it('valid', async () => {
39+
const sdk = await initSDKTest()
40+
const json = getSampleRPCSettingsResponse()
41+
const encode = sdk.rhp.encodeSettingsResponse(json)
42+
expect(encode.rpc).toBeDefined()
43+
expect(encode.rpc?.length).toEqual(323)
44+
expect(encode.error).toBeUndefined()
45+
const decode = sdk.rhp.decodeSettingsResponse(encode.rpc!)
46+
expect(decode.data).toEqual(json)
47+
expect(decode.error).toBeUndefined()
48+
})
49+
it('encode error', async () => {
50+
const sdk = await initSDKTest()
51+
const json = {
52+
settings: {
53+
walletAddress: 'invalid',
54+
},
55+
} as RPCSettingsResponse
56+
const encode = sdk.rhp.encodeSettingsResponse(json)
57+
expect(encode.rpc).toBeUndefined()
58+
expect(encode.error).toEqual(
59+
"decoding addr:<hex> failed: encoding/hex: invalid byte: U+0069 'i'"
60+
)
61+
})
62+
it('decode error', async () => {
63+
const sdk = await initSDKTest()
64+
const json = getSampleRPCSettingsResponse()
65+
const encode = sdk.rhp.encodeSettingsResponse(json)
66+
// manipulate the valid rpc to make it invalid
67+
encode.rpc!.set([1, 1], 30)
68+
const decode = sdk.rhp.decodeSettingsResponse(encode.rpc!)
69+
expect(decode.data).not.toEqual(json)
70+
expect(decode.error).toEqual(
71+
'encoded object contains invalid length prefix (65806 elems > 11227 bytes left in stream)'
72+
)
73+
})
74+
})
75+
})
76+
describe('read', () => {
77+
describe('request', () => {
78+
it('valid', async () => {
79+
const sdk = await initSDKTest()
80+
const json: RPCReadSectorRequest = {
81+
token: {
82+
account:
83+
'acct:1b6793e900df020dc9a43c6df5f5d10dc5793956d44831ca5bbfec659021b75e',
84+
validUntil: '2022-12-31T00:00:00Z',
85+
signature:
86+
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
87+
},
88+
root: 'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
89+
prices: getSampleHostPrices(),
90+
offset: 0,
91+
length: 4,
92+
}
93+
const encode = sdk.rhp.encodeReadSectorRequest(json)
94+
expect(encode.rpc?.length).toEqual(312)
95+
expect(encode.error).toBeUndefined()
96+
const decode = sdk.rhp.decodeReadSectorRequest(encode.rpc!)
97+
expect(decode.data).toEqual(json)
98+
expect(decode.error).toBeUndefined()
99+
})
100+
it('encode error', async () => {
101+
const sdk = await initSDKTest()
102+
const json: RPCReadSectorRequest = {
103+
token: {
104+
account: 'invalid',
105+
validUntil: '2022-12-31T00:00:00Z',
106+
signature:
107+
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
108+
},
109+
root: 'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
110+
prices: getSampleHostPrices(),
111+
offset: 0,
112+
length: 4,
113+
}
114+
const encode = sdk.rhp.encodeReadSectorRequest(json)
115+
expect(encode.rpc).toBeUndefined()
116+
expect(encode.error).toEqual(
117+
"decoding acct:<hex> failed: encoding/hex: invalid byte: U+0069 'i'"
118+
)
119+
})
120+
})
121+
describe('response', () => {
122+
it('valid', async () => {
123+
const sdk = await initSDKTest()
124+
const json: RPCReadSectorResponse = {
125+
proof: [
126+
'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
127+
],
128+
sector: 'AQID',
129+
}
130+
const encode = sdk.rhp.encodeReadSectorResponse(json)
131+
expect(encode.rpc?.toString()).toEqual(
132+
[
133+
0, 1, 0, 0, 0, 0, 0, 0, 0, 69, 114, 86, 214, 161, 96, 59, 239, 127,
134+
169, 87, 167, 11, 91, 169, 106, 157, 239, 47, 234, 139, 76, 20, 131,
135+
6, 13, 123, 165, 207, 138, 7, 44, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
136+
].toString()
137+
)
138+
expect(encode.error).toBeUndefined()
139+
const decode = sdk.rhp.decodeReadSectorResponse(encode.rpc!)
140+
expect(decode.data).toEqual(json)
141+
expect(decode.error).toBeUndefined()
142+
})
143+
it('encode error', async () => {
144+
const sdk = await initSDKTest()
145+
const json: RPCReadSectorResponse = {
146+
proof: ['invalid'],
147+
sector: 'AQID',
148+
}
149+
const encode = sdk.rhp.encodeReadSectorResponse(json)
150+
expect(encode.rpc).toBeUndefined()
151+
expect(encode.error).toEqual('decoding h:<hex> failed: unexpected EOF')
152+
})
153+
})
154+
})
155+
describe('write', () => {
156+
describe('request', () => {
157+
it('valid', async () => {
158+
const sdk = await initSDKTest()
159+
const json: RPCWriteSectorRequest = {
160+
token: {
161+
account:
162+
'acct:1b6793e900df020dc9a43c6df5f5d10dc5793956d44831ca5bbfec659021b75e',
163+
validUntil: '2022-12-31T00:00:00Z',
164+
signature:
165+
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
166+
},
167+
sector: 'AQID',
168+
prices: getSampleHostPrices(),
169+
}
170+
const encode = sdk.rhp.encodeWriteSectorRequest(json)
171+
expect(encode.rpc?.length).toEqual(275)
172+
expect(encode.error).toBeUndefined()
173+
const decode = sdk.rhp.decodeWriteSectorRequest(encode.rpc!)
174+
expect(decode.data).toEqual(json)
175+
expect(decode.error).toBeUndefined()
176+
})
177+
it('encode error', async () => {
178+
const sdk = await initSDKTest()
179+
const json = {
180+
token: {
181+
account: 'invalid',
182+
validUntil: '2022-12-31T00:00:00Z',
183+
signature:
184+
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
185+
},
186+
sector: 'AQID',
187+
prices: getSampleHostPrices(),
188+
} as RPCWriteSectorRequest
189+
const encode = sdk.rhp.encodeWriteSectorRequest(json)
190+
expect(encode.rpc).toBeUndefined()
191+
expect(encode.error).toEqual(
192+
"decoding acct:<hex> failed: encoding/hex: invalid byte: U+0069 'i'"
193+
)
194+
})
195+
})
196+
describe('response', () => {
197+
it('valid', async () => {
198+
const sdk = await initSDKTest()
199+
const json: RPCWriteSectorResponse = {
200+
root: 'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
201+
}
202+
const encode = sdk.rhp.encodeWriteSectorResponse(json)
203+
expect(encode.rpc?.toString()).toEqual(
204+
[
205+
0, 69, 114, 86, 214, 161, 96, 59, 239, 127, 169, 87, 167, 11, 91,
206+
169, 106, 157, 239, 47, 234, 139, 76, 20, 131, 6, 13, 123, 165, 207,
207+
138, 7, 44,
208+
].toString()
209+
)
210+
expect(encode.error).toBeUndefined()
211+
const decode = sdk.rhp.decodeWriteSectorResponse(encode.rpc!)
212+
expect(decode.data).toEqual(json)
213+
expect(decode.error).toBeUndefined()
214+
})
215+
it('encode error', async () => {
216+
const sdk = await initSDKTest()
217+
const json = {
218+
root: 'invalid',
219+
} as RPCWriteSectorResponse
220+
const encode = sdk.rhp.encodeWriteSectorResponse(json)
221+
expect(encode.rpc).toBeUndefined()
222+
expect(encode.error).toEqual('decoding h:<hex> failed: unexpected EOF')
223+
})
224+
})
225+
})
226+
})
227+
228+
function getSampleHostPrices(): HostPrices {
229+
return {
230+
contractPrice: '1000000000',
231+
collateral: '2000000000',
232+
storagePrice: '3000000000',
233+
ingressPrice: '4000000000',
234+
egressPrice: '5000000000',
235+
tipHeight: 450_000,
236+
validUntil: '2022-12-31T00:00:00Z',
237+
signature:
238+
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
239+
}
240+
}
241+
242+
function getSampleRPCSettingsResponse(): RPCSettingsResponse {
243+
const prices = getSampleHostPrices()
244+
const settings: HostSettings = {
245+
version: [1, 2, 3],
246+
netAddresses: [
247+
{ protocol: 'protocol1', address: 'address1longer' },
248+
{ protocol: 'protocol2longer', address: 'address2' },
249+
],
250+
// 32 bytes
251+
walletAddress:
252+
'addr:eec8160897cf7058332040675d120c008dc32d96925e9b32a812b646e31676d7d52c118cad2c',
253+
acceptingContracts: true,
254+
maxCollateral: '1000000000',
255+
maxDuration: 100,
256+
remainingStorage: 100,
257+
totalStorage: 100,
258+
prices,
259+
}
260+
return {
261+
settings,
262+
}
263+
}

libs/sdk/src/sdk.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export function getSDK() {
55
// eslint-disable-next-line @typescript-eslint/no-explicit-any
66
const wasm = (global as any).sia as WASM
77
return {
8-
wasm,
8+
rhp: wasm.rhp,
99
WebTransportClient,
1010
}
1111
}

libs/sdk/src/types.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,8 @@ export type RPC = RPCSettings | RPCReadSector | RPCWriteSector
8888
export type WASM = {
8989
rhp: {
9090
generateAccount: () => {
91-
data?: {
92-
privateKey: PrivateKey
93-
account?: PublicKey
94-
}
91+
privateKey?: PrivateKey
92+
account?: PublicKey
9593
error?: string
9694
}
9795
// settings

0 commit comments

Comments
 (0)