Skip to content

Commit d26a952

Browse files
committed
refactor: sdk tweaks and add to walletd
1 parent 815ef68 commit d26a952

File tree

19 files changed

+126
-58
lines changed

19 files changed

+126
-58
lines changed

.changeset/fast-suits-punch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@siafoundation/sdk': minor
3+
---
4+
5+
signTransaction has been updated to the more specific signTransactionV1.

.changeset/honest-falcons-rhyme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@siafoundation/sdk': minor
3+
---
4+
5+
WebTransportClient no longer requires the SDK API as an explicit constructor parameter.

.github/workflows/pr.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,14 @@ jobs:
3232
uses: golangci/golangci-lint-action@v3
3333
with:
3434
skip-cache: true
35-
- name: NX pre-build compile targets
35+
# The SDK is referenced via dist in the tsconfig.base.json
36+
# because the next executor does not actually support
37+
# buildLibsFromSource=false
38+
# With this configuration NX does not build the SDK as expected
39+
# when it is an app dependency
40+
- name: Force build SDK
3641
shell: bash
37-
run: npx nx affected --target=compile --parallel=5
42+
run: npx nx run sdk:build
3843
- name: Test TypeScript
3944
shell: bash
4045
run: npx nx affected --target=test --parallel=5

.github/workflows/release-main.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,14 @@ jobs:
3636
uses: golangci/golangci-lint-action@v3
3737
with:
3838
skip-cache: true
39-
- name: NX pre-build compile targets
39+
# The SDK is referenced via dist in the tsconfig.base.json
40+
# because the next executor does not actually support
41+
# buildLibsFromSource=false
42+
# With this configuration NX does not build the SDK as expected
43+
# when it is an app dependency
44+
- name: Force build SDK
4045
shell: bash
41-
run: npx nx run-many --target=compile --all --parallel=5
46+
run: npx nx run sdk:build
4247
- name: Test TypeScript
4348
shell: bash
4449
run: npx nx run-many --target=test --all --parallel=5

apps/walletd-e2e/project.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"$schema": "../../node_modules/nx/schemas/project-schema.json",
44
"sourceRoot": "apps/walletd-e2e/src",
55
"projectType": "application",
6+
"implicitDependencies": ["walletd"],
67
"targets": {
78
"e2e": {
89
"executor": "@nx/playwright:playwright",
@@ -14,6 +15,5 @@
1415
"lint": {
1516
"executor": "@nx/eslint:lint"
1617
}
17-
},
18-
"implicitDependencies": ["walletd"]
18+
}
1919
}

apps/walletd/config/providers.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,29 @@ import { WalletsProvider } from '../contexts/wallets'
44
import { AddressesProvider } from '../contexts/addresses'
55
import { EventsProvider } from '../contexts/events'
66
import { LedgerProvider } from '../contexts/ledger'
7+
import { AppProvider } from '../contexts/app'
78

89
type Props = {
910
children: React.ReactNode
1011
}
1112

1213
export function Providers({ children }: Props) {
1314
return (
14-
<DialogProvider>
15-
<LedgerProvider>
16-
<WalletsProvider>
17-
<AddressesProvider>
18-
<EventsProvider>
19-
{/* this is here so that dialogs can use all the other providers,
15+
<AppProvider>
16+
<DialogProvider>
17+
<LedgerProvider>
18+
<WalletsProvider>
19+
<AddressesProvider>
20+
<EventsProvider>
21+
{/* this is here so that dialogs can use all the other providers,
2022
and the other providers can trigger dialogs */}
21-
<Dialogs />
22-
{children}
23-
</EventsProvider>
24-
</AddressesProvider>
25-
</WalletsProvider>
26-
</LedgerProvider>
27-
</DialogProvider>
23+
<Dialogs />
24+
{children}
25+
</EventsProvider>
26+
</AddressesProvider>
27+
</WalletsProvider>
28+
</LedgerProvider>
29+
</DialogProvider>
30+
</AppProvider>
2831
)
2932
}

apps/walletd/contexts/app/index.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { createContext, useContext, useEffect } from 'react'
2+
import { initSDK } from '@siafoundation/sdk'
3+
4+
function useAppMain() {
5+
// Initialize the SDK on app load
6+
useEffect(() => {
7+
const func = async () => {
8+
await initSDK()
9+
}
10+
func()
11+
}, [])
12+
return {}
13+
}
14+
15+
type State = ReturnType<typeof useAppMain>
16+
17+
const AppContext = createContext({} as State)
18+
export const useApp = () => useContext(AppContext)
19+
20+
type Props = {
21+
children: React.ReactNode
22+
}
23+
24+
export function AppProvider({ children }: Props) {
25+
const state = useAppMain()
26+
return <AppContext.Provider value={state}>{children}</AppContext.Provider>
27+
}

apps/walletd/project.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"$schema": "../../node_modules/nx/schemas/project-schema.json",
44
"sourceRoot": "apps/walletd",
55
"projectType": "application",
6+
"implicitDependencies": ["sdk"],
67
"targets": {
78
"build": {
89
"executor": "@nx/next:build",
@@ -67,6 +68,7 @@
6768
"test": {
6869
"executor": "@nx/jest:jest",
6970
"outputs": ["{workspaceRoot}/coverage/apps/walletd"],
71+
"dependsOn": ["sdk:build"],
7072
"options": {
7173
"jestConfig": "apps/walletd/jest.config.ts"
7274
}

libs/sdk/project.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
"projectType": "library",
66
"tags": [],
77
"namedInputs": {
8-
"go": ["{workspaceRoot}/sdk/**/*"],
9-
"production": ["default", "go"]
8+
"go": ["{workspaceRoot}/sdk/**/*"]
109
},
1110
"targets": {
1211
"compile": {
@@ -24,7 +23,6 @@
2423
"executor": "@nx/rollup:rollup",
2524
"outputs": ["{options.outputPath}"],
2625
"dependsOn": ["compile", "^build"],
27-
"inputs": ["production", "^production"],
2826
"options": {
2927
"outputPath": "dist/libs/sdk",
3028
"tsConfig": "libs/sdk/tsconfig.lib.json",

libs/sdk/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
export * from './init'
21
export * from './types'
2+
export { initSDK } from './init'
3+
export { getSDK } from './sdk'
4+
export type { SDK } from './sdk'

libs/sdk/src/sdk.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
import { WebTransportClient } from './transport'
2-
import { WASM } from './types'
2+
import { WasmApi } from './types'
33

4-
export function getSDK() {
4+
export type SDK = WasmApi & {
5+
WebTransportClient: typeof WebTransportClient
6+
}
7+
8+
export function getWasmApi(): WasmApi {
59
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6-
const wasm = (global as any).sia as WASM
10+
return (globalThis as any).sia as WasmApi
11+
}
12+
13+
export function getSDK(): SDK {
14+
const wasmApi = getWasmApi()
15+
if (wasmApi === undefined) {
16+
throw new Error('The Sia SDK has not been initialized')
17+
}
718
return {
8-
rhp: wasm.rhp,
9-
wallet: wasm.wallet,
19+
...wasmApi,
1020
WebTransportClient,
1121
}
1222
}

libs/sdk/src/transport.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getWasmApi } from './sdk'
12
import {
23
RPCReadSectorResponse,
34
RPCSettingsResponse,
@@ -9,26 +10,27 @@ import {
910
RPCWriteSector,
1011
RPCSettings,
1112
} from './types'
12-
import { WASM } from './types'
1313

1414
export class WebTransportClient {
1515
#url: string
1616
#cert: string
17-
#wasm: WASM
1817

1918
#transport!: WebTransport
2019

21-
constructor(url: string, cert: string, wasm: WASM) {
20+
constructor(url: string, cert: string) {
2221
this.#url = url
2322
this.#cert = cert
24-
this.#wasm = wasm
25-
}
2623

27-
async connect() {
24+
if (!getWasmApi()) {
25+
throw new Error('The Sia SDK has not been initialized.')
26+
}
27+
2828
if (!('WebTransport' in window)) {
2929
throw new Error('WebTransport is not supported in your browser.')
3030
}
31+
}
3132

33+
async connect() {
3234
try {
3335
this.#transport = new WebTransport(this.#url, {
3436
serverCertificateHashes: this.#cert
@@ -101,8 +103,8 @@ export class WebTransportClient {
101103
): Promise<RPCReadSectorResponse> {
102104
return this.sendRequest<RPCReadSector>(
103105
readSector,
104-
this.#wasm.rhp.encodeReadSectorRequest,
105-
this.#wasm.rhp.decodeReadSectorResponse
106+
getWasmApi().rhp.encodeReadSectorRequest,
107+
getWasmApi().rhp.decodeReadSectorResponse
106108
)
107109
}
108110

@@ -111,16 +113,16 @@ export class WebTransportClient {
111113
): Promise<RPCWriteSectorResponse> {
112114
return this.sendRequest<RPCWriteSector>(
113115
writeSector,
114-
this.#wasm.rhp.encodeWriteSectorRequest,
115-
this.#wasm.rhp.decodeWriteSectorResponse
116+
getWasmApi().rhp.encodeWriteSectorRequest,
117+
getWasmApi().rhp.decodeWriteSectorResponse
116118
)
117119
}
118120

119121
async sendRPCSettingsRequest(): Promise<RPCSettingsResponse> {
120122
return this.sendRequest<RPCSettings>(
121123
undefined,
122-
this.#wasm.rhp.encodeSettingsRequest,
123-
this.#wasm.rhp.decodeSettingsResponse
124+
getWasmApi().rhp.encodeSettingsRequest,
125+
getWasmApi().rhp.decodeSettingsResponse
124126
)
125127
}
126128
}

libs/sdk/src/types.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ import {
33
UnlockConditions,
44
ConsensusNetwork,
55
ConsensusState,
6+
Currency,
7+
Signature,
8+
Address,
9+
Hash256,
10+
PublicKey,
11+
PrivateKey,
612
} from '@siafoundation/types'
713

8-
type Currency = string
9-
type Signature = string
10-
type Address = string
11-
type Hash256 = string // 32 bytes
12-
type PrivateKey = string
13-
type PublicKey = string // 32 bytes
14-
1514
type AccountToken = {
1615
account: PublicKey
1716
validUntil: string
@@ -92,7 +91,7 @@ export type RPCWriteSector = {
9291

9392
export type RPC = RPCSettings | RPCReadSector | RPCWriteSector
9493

95-
export type WASM = {
94+
export type WasmApi = {
9695
rhp: {
9796
generateAccount: () => {
9897
privateKey?: PrivateKey
@@ -189,7 +188,7 @@ export type WASM = {
189188
encodedTransaction?: string
190189
error?: string
191190
}
192-
signTransaction: (
191+
signTransactionV1: (
193192
cs: ConsensusState,
194193
cn: ConsensusNetwork,
195194
txn: Transaction,

libs/sdk/src/wallet.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ describe('wallet', () => {
151151
it('signs a valid transaction', async () => {
152152
const sdk = await initSDKTest()
153153
const { privateKey } = sdk.wallet.keyPairFromSeedPhrase(mockPhrase!, 0)
154-
const { error, signature } = sdk.wallet.signTransaction(
154+
const { error, signature } = sdk.wallet.signTransactionV1(
155155
getConsensusState(),
156156
getConsensusNetwork(),
157157
getTransaction(),
@@ -160,13 +160,13 @@ describe('wallet', () => {
160160
)
161161
expect(error).toBeUndefined()
162162
expect(signature).toEqual(
163-
'sig:c58f8fe1ee5a08147484a53af7d3a64eca8039794b6c475342f0d8927b04d3172b3ed72861c183c73e87d719b782fb291dbfe8b3e0b1088095a9264bc97b6f06'
163+
'xY+P4e5aCBR0hKU699OmTsqAOXlLbEdTQvDYknsE0xcrPtcoYcGDxz6H1xm3gvspHb/os+CxCICVqSZLyXtvBg=='
164164
)
165165
})
166166
it('errors if the signature index is invalid', async () => {
167167
const sdk = await initSDKTest()
168168
const { privateKey } = sdk.wallet.keyPairFromSeedPhrase(mockPhrase!, 0)
169-
const { error, signature } = sdk.wallet.signTransaction(
169+
const { error, signature } = sdk.wallet.signTransactionV1(
170170
getConsensusState(),
171171
getConsensusNetwork(),
172172
getTransaction(),
@@ -178,7 +178,7 @@ describe('wallet', () => {
178178
})
179179
it('errors if the private key is invalid', async () => {
180180
const sdk = await initSDKTest()
181-
const { error, signature } = sdk.wallet.signTransaction(
181+
const { error, signature } = sdk.wallet.signTransactionV1(
182182
getConsensusState(),
183183
getConsensusNetwork(),
184184
getTransaction(),

libs/sdk/src/wasm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export async function initWASM(): Promise<void> {
55
try {
66
const go = new window.Go()
77
const source = await wasm(go.importObject)
8-
await go.run(source.instance)
8+
go.run(source.instance)
99
} catch (e) {
1010
throw new Error(`failed to initialize WASM: ${(e as Error).message}`)
1111
}

libs/types/src/core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type OutputID = string
88
export type EncryptionKey = string
99
export type FileContractID = string
1010
export type PublicKey = string
11+
export type PrivateKey = string
1112
export type TransactionID = Hash256
1213
export type SiacoinOutputID = Hash256
1314
export type SiafundOutputID = Hash256

sdk/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func main() {
3434
"addressFromSpendPolicy": jsFunc(addressFromSpendPolicy),
3535
"encodeTransaction": jsFunc(encodeTransaction),
3636
"transactionId": jsFunc(transactionID),
37-
"signTransaction": jsFunc(signTransaction),
37+
"signTransactionV1": jsFunc(signTransactionV1),
3838
},
3939
})
4040
c := make(chan bool, 1)

sdk/wallet.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"bytes"
55
"crypto/ed25519"
6+
"encoding/base64"
67
"encoding/hex"
78
"fmt"
89
"syscall/js"
@@ -146,7 +147,7 @@ func encodeTransaction(this js.Value, args []js.Value) result {
146147
}
147148

148149
// SignTransaction returns the signature of a transaction.
149-
func signTransaction(this js.Value, args []js.Value) result {
150+
func signTransactionV1(this js.Value, args []js.Value) result {
150151
if err := checkArgs(args, js.TypeObject, js.TypeObject, js.TypeObject, js.TypeNumber, js.TypeString); err != nil {
151152
return resultErr(err)
152153
}
@@ -187,8 +188,9 @@ func signTransaction(this js.Value, args []js.Value) result {
187188
} else {
188189
sigHash = cs.PartialSigHash(txn, tsig.CoveredFields)
189190
}
191+
sig := privateKey.SignHash(sigHash)
190192
return result(map[string]any{
191-
"signature": privateKey.SignHash(sigHash).String(),
193+
"signature": base64.StdEncoding.EncodeToString(sig[:]),
192194
})
193195
}
194196

0 commit comments

Comments
 (0)