Skip to content

Commit

Permalink
refactor: migrate wallet wasm into sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Feb 29, 2024
1 parent b72d59b commit d350da4
Show file tree
Hide file tree
Showing 13 changed files with 636 additions and 310 deletions.
5 changes: 5 additions & 0 deletions .changeset/real-carrots-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/sdk': minor
---

Wallet and transaction signing methods are now part of the sdk.
2 changes: 1 addition & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ runs:
registry-url: https://registry.npmjs.org
- uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: '1.21.7'
- uses: acifani/setup-tinygo@v2
with:
tinygo-version: '0.30.0'
Expand Down
4 changes: 2 additions & 2 deletions go.work
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
go 1.20
go 1.21.7

use (
./
./hostd
./renterd
./walletd
./sdk
./walletd
)
10 changes: 10 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M=
go.sia.tech/mux v1.2.0/go.mod h1:Yyo6wZelOYTyvrHmJZ6aQfRoer3o4xyKQ4NmQLJrBSo=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
283 changes: 283 additions & 0 deletions libs/sdk/src/rhp.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
import {
HostPrices,
HostSettings,
RPCReadSectorRequest,
RPCReadSectorResponse,
RPCSettingsResponse,
RPCWriteSectorRequest,
RPCWriteSectorResponse,
} from './types'
import { initSDKTest } from './initTest'

describe('rhp', () => {
describe('generateAccout', () => {
it('works', async () => {
const sdk = await initSDKTest()
const { privateKey, account, error } = sdk.rhp.generateAccount()
expect(error).toBeUndefined()
expect(privateKey).toBeDefined()
expect(privateKey?.length).toBeGreaterThan(40)
expect(account).toBeDefined()
expect(account?.length).toBeGreaterThan(40)
})
})
describe('settings', () => {
describe('request', () => {
it('valid', async () => {
const sdk = await initSDKTest()
const encode = sdk.rhp.encodeSettingsRequest()
expect(encode.rpc).toBeDefined()
expect(encode.error).not.toBeDefined()
if (!encode.rpc) {
throw new Error('rpc is undefined')
}
const decode = sdk.rhp.decodeSettingsRequest(encode.rpc)
expect(decode.data).toEqual({})
expect(decode.error).toBeUndefined()
})
})
describe('response', () => {
it('valid', async () => {
const sdk = await initSDKTest()
const json = getSampleRPCSettingsResponse()
const encode = sdk.rhp.encodeSettingsResponse(json)
expect(encode.rpc).toBeDefined()
expect(encode.rpc?.length).toEqual(323)
expect(encode.error).toBeUndefined()
if (!encode.rpc) {
throw new Error('rpc is undefined')
}
const decode = sdk.rhp.decodeSettingsResponse(encode.rpc)
expect(decode.data).toEqual(json)
expect(decode.error).toBeUndefined()
})
it('encode error', async () => {
const sdk = await initSDKTest()
const json = {
settings: {
walletAddress: 'invalid',
},
} as RPCSettingsResponse
const encode = sdk.rhp.encodeSettingsResponse(json)
expect(encode.rpc).toBeUndefined()
expect(encode.error).toEqual(
"decoding addr:<hex> failed: encoding/hex: invalid byte: U+0069 'i'"
)
})
it('decode error', async () => {
const sdk = await initSDKTest()
const json = getSampleRPCSettingsResponse()
const encode = sdk.rhp.encodeSettingsResponse(json)
if (!encode.rpc) {
throw new Error('rpc is undefined')
}
// manipulate the valid rpc to make it invalid
encode.rpc.set([1, 1], 30)
const decode = sdk.rhp.decodeSettingsResponse(encode.rpc)
expect(decode.data).not.toEqual(json)
expect(decode.error).toEqual(
'encoded object contains invalid length prefix (65806 elems > 11227 bytes left in stream)'
)
})
})
})
describe('read', () => {
describe('request', () => {
it('valid', async () => {
const sdk = await initSDKTest()
const json: RPCReadSectorRequest = {
token: {
account:
'acct:1b6793e900df020dc9a43c6df5f5d10dc5793956d44831ca5bbfec659021b75e',
validUntil: '2022-12-31T00:00:00Z',
signature:
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
},
root: 'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
prices: getSampleHostPrices(),
offset: 0,
length: 4,
}
const encode = sdk.rhp.encodeReadSectorRequest(json)
expect(encode.rpc?.length).toEqual(312)
expect(encode.error).toBeUndefined()
if (!encode.rpc) {
throw new Error('rpc is undefined')
}
const decode = sdk.rhp.decodeReadSectorRequest(encode.rpc)
expect(decode.data).toEqual(json)
expect(decode.error).toBeUndefined()
})
it('encode error', async () => {
const sdk = await initSDKTest()
const json: RPCReadSectorRequest = {
token: {
account: 'invalid',
validUntil: '2022-12-31T00:00:00Z',
signature:
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
},
root: 'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
prices: getSampleHostPrices(),
offset: 0,
length: 4,
}
const encode = sdk.rhp.encodeReadSectorRequest(json)
expect(encode.rpc).toBeUndefined()
expect(encode.error).toEqual(
"decoding acct:<hex> failed: encoding/hex: invalid byte: U+0069 'i'"
)
})
})
describe('response', () => {
it('valid', async () => {
const sdk = await initSDKTest()
const json: RPCReadSectorResponse = {
proof: [
'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
],
sector: 'AQID',
}
const encode = sdk.rhp.encodeReadSectorResponse(json)
expect(encode.rpc?.toString()).toEqual(
[
0, 1, 0, 0, 0, 0, 0, 0, 0, 69, 114, 86, 214, 161, 96, 59, 239, 127,
169, 87, 167, 11, 91, 169, 106, 157, 239, 47, 234, 139, 76, 20, 131,
6, 13, 123, 165, 207, 138, 7, 44, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
].toString()
)
expect(encode.error).toBeUndefined()
if (!encode.rpc) {
throw new Error('rpc is undefined')
}
const decode = sdk.rhp.decodeReadSectorResponse(encode.rpc)
expect(decode.data).toEqual(json)
expect(decode.error).toBeUndefined()
})
it('encode error', async () => {
const sdk = await initSDKTest()
const json: RPCReadSectorResponse = {
proof: ['invalid'],
sector: 'AQID',
}
const encode = sdk.rhp.encodeReadSectorResponse(json)
expect(encode.rpc).toBeUndefined()
expect(encode.error).toEqual('decoding h:<hex> failed: unexpected EOF')
})
})
})
describe('write', () => {
describe('request', () => {
it('valid', async () => {
const sdk = await initSDKTest()
const json: RPCWriteSectorRequest = {
token: {
account:
'acct:1b6793e900df020dc9a43c6df5f5d10dc5793956d44831ca5bbfec659021b75e',
validUntil: '2022-12-31T00:00:00Z',
signature:
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
},
sector: 'AQID',
prices: getSampleHostPrices(),
}
const encode = sdk.rhp.encodeWriteSectorRequest(json)
expect(encode.rpc?.length).toEqual(275)
expect(encode.error).toBeUndefined()
if (!encode.rpc) {
throw new Error('rpc is undefined')
}
const decode = sdk.rhp.decodeWriteSectorRequest(encode.rpc)
expect(decode.data).toEqual(json)
expect(decode.error).toBeUndefined()
})
it('encode error', async () => {
const sdk = await initSDKTest()
const json = {
token: {
account: 'invalid',
validUntil: '2022-12-31T00:00:00Z',
signature:
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
},
sector: 'AQID',
prices: getSampleHostPrices(),
} as RPCWriteSectorRequest
const encode = sdk.rhp.encodeWriteSectorRequest(json)
expect(encode.rpc).toBeUndefined()
expect(encode.error).toEqual(
"decoding acct:<hex> failed: encoding/hex: invalid byte: U+0069 'i'"
)
})
})
describe('response', () => {
it('valid', async () => {
const sdk = await initSDKTest()
const json: RPCWriteSectorResponse = {
root: 'h:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072c',
}
const encode = sdk.rhp.encodeWriteSectorResponse(json)
expect(encode.rpc?.toString()).toEqual(
[
0, 69, 114, 86, 214, 161, 96, 59, 239, 127, 169, 87, 167, 11, 91,
169, 106, 157, 239, 47, 234, 139, 76, 20, 131, 6, 13, 123, 165, 207,
138, 7, 44,
].toString()
)
expect(encode.error).toBeUndefined()
if (!encode.rpc) {
throw new Error('rpc is undefined')
}
const decode = sdk.rhp.decodeWriteSectorResponse(encode.rpc)
expect(decode.data).toEqual(json)
expect(decode.error).toBeUndefined()
})
it('encode error', async () => {
const sdk = await initSDKTest()
const json = {
root: 'invalid',
} as RPCWriteSectorResponse
const encode = sdk.rhp.encodeWriteSectorResponse(json)
expect(encode.rpc).toBeUndefined()
expect(encode.error).toEqual('decoding h:<hex> failed: unexpected EOF')
})
})
})
})

function getSampleHostPrices(): HostPrices {
return {
contractPrice: '1000000000',
collateral: '2000000000',
storagePrice: '3000000000',
ingressPrice: '4000000000',
egressPrice: '5000000000',
tipHeight: 450_000,
validUntil: '2022-12-31T00:00:00Z',
signature:
'sig:457256d6a1603bef7fa957a70b5ba96a9def2fea8b4c1483060d7ba5cf8a072cfddf242a1ef033dd7d669c711e846c59cb916f804a03d72d279ffef7e6583404',
}
}

function getSampleRPCSettingsResponse(): RPCSettingsResponse {
const prices = getSampleHostPrices()
const settings: HostSettings = {
version: [1, 2, 3],
netAddresses: [
{ protocol: 'protocol1', address: 'address1longer' },
{ protocol: 'protocol2longer', address: 'address2' },
],
// 32 bytes
walletAddress:
'addr:eec8160897cf7058332040675d120c008dc32d96925e9b32a812b646e31676d7d52c118cad2c',
acceptingContracts: true,
maxCollateral: '1000000000',
maxDuration: 100,
remainingStorage: 100,
totalStorage: 100,
prices,
}
return {
settings,
}
}
3 changes: 2 additions & 1 deletion libs/sdk/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export function getSDK() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const wasm = (global as any).sia as WASM
return {
wasm,
rhp: wasm.rhp,
wallet: wasm.wallet,
WebTransportClient,
}
}
Loading

0 comments on commit d350da4

Please sign in to comment.