Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions core/signing-internal/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ export class InternalSigningDriver implements SigningDriverInterface {
hash: params.txHash,
signature,
publicKey: params.publicKey,
createdAt: new Date(),
createdAt: new Date().toISOString(),
status: 'signed',
updatedAt: new Date(),
updatedAt: new Date().toISOString(),
}

this.store.setSigningTransaction(
Expand Down Expand Up @@ -175,6 +175,7 @@ export class InternalSigningDriver implements SigningDriverInterface {
convertInternalTransaction({
...tx,
signature: tx.signature || 'signed',
createdAt: new Date(tx.createdAt),
})
),
})
Expand Down Expand Up @@ -230,8 +231,8 @@ export class InternalSigningDriver implements SigningDriverInterface {
name: params.name,
publicKey,
privateKey,
createdAt: new Date(),
updatedAt: new Date(),
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}

await this.store.setSigningKey(_userId, internalKey)
Expand Down
8 changes: 4 additions & 4 deletions core/signing-lib/src/SigningDriverStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export interface SigningKey {
publicKey: string
privateKey?: string // Optional for external providers like Fireblocks
metadata?: Record<string, unknown> // Driver-specific data (e.g., derivation path)
createdAt: Date
updatedAt: Date
createdAt: string
updatedAt: string
}

/**
Expand All @@ -82,8 +82,8 @@ export interface SigningTransaction {
publicKey: string
status: SigningDriverStatus
metadata?: Record<string, unknown> // Driver-specific data
createdAt: Date
updatedAt: Date
createdAt: string
updatedAt: string
}

/**
Expand Down
2 changes: 2 additions & 0 deletions core/signing-store-sql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@
"better-sqlite3": "^12.2.0",
"commander": "^14.0.0",
"kysely": "^0.28.5",
"pg": "^8.16.3",
"pino": "^10.0.0",
"umzug": "^3.8.2",
"zod": "^3.25.64"
},
"devDependencies": {
"@swc/core": "^1.11.31",
"@types/better-sqlite3": "^7.6.13",
"@types/pg": "^8",
"tsup": "^8.5.0",
"tsx": "^4.20.4",
"typescript": "^5.8.3"
Expand Down
8 changes: 4 additions & 4 deletions core/signing-store-sql/src/migrations/001-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export async function up(db: Kysely<DB>): Promise<void> {
.addColumn('public_key', 'text', (col) => col.notNull())
.addColumn('private_key', 'text') // Encrypted for internal driver
.addColumn('metadata', 'text') // JSON string for driver-specific data
.addColumn('created_at', 'integer', (col) => col.notNull())
.addColumn('updated_at', 'integer', (col) => col.notNull())
.addColumn('created_at', 'text', (col) => col.notNull())
.addColumn('updated_at', 'text', (col) => col.notNull())
.addUniqueConstraint('signing_keys_user_id_id_unique', [
'user_id',
'id',
Expand All @@ -36,8 +36,8 @@ export async function up(db: Kysely<DB>): Promise<void> {
.addColumn('public_key', 'text', (col) => col.notNull())
.addColumn('status', 'text', (col) => col.notNull())
.addColumn('metadata', 'text') // JSON string for driver-specific data
.addColumn('created_at', 'integer', (col) => col.notNull())
.addColumn('updated_at', 'integer', (col) => col.notNull())
.addColumn('created_at', 'text', (col) => col.notNull())
.addColumn('updated_at', 'text', (col) => col.notNull())
.addUniqueConstraint('signing_transactions_user_id_id_unique', [
'user_id',
'id',
Expand Down
39 changes: 28 additions & 11 deletions core/signing-store-sql/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ export const fromSigningKey = (
: key.privateKey
: null,
metadata: key.metadata ? JSON.stringify(key.metadata) : null,
createdAt: key.createdAt.toISOString(),
updatedAt: key.updatedAt.toISOString(),
createdAt: key.createdAt,
updatedAt: key.updatedAt,
}
}

Expand All @@ -89,9 +89,16 @@ export const toSigningKey = (
: table.privateKey,
}
: {}),
createdAt: new Date(table.createdAt),
updatedAt: new Date(table.updatedAt),
...(table.metadata ? { metadata: JSON.parse(table.metadata) } : {}),
createdAt: table.createdAt,
updatedAt: table.updatedAt,
...(table.metadata
? {
metadata:
typeof table.metadata === 'string'
? JSON.parse(table.metadata)
: table.metadata,
}
: {}),
}
}

Expand All @@ -109,8 +116,8 @@ export const fromSigningTransaction = (
metadata: transaction.metadata
? JSON.stringify(transaction.metadata)
: null,
createdAt: transaction.createdAt.toISOString(),
updatedAt: transaction.updatedAt.toISOString(),
createdAt: transaction.createdAt,
updatedAt: transaction.updatedAt,
}
}

Expand All @@ -123,9 +130,16 @@ export const toSigningTransaction = (
...(table.signature ? { signature: table.signature } : {}),
publicKey: table.publicKey,
status: table.status as SigningDriverStatus,
...(table.metadata ? { metadata: JSON.parse(table.metadata) } : {}),
createdAt: new Date(table.createdAt),
updatedAt: new Date(table.updatedAt),
...(table.metadata
? {
metadata:
typeof table.metadata === 'string'
? JSON.parse(table.metadata)
: table.metadata,
}
: {}),
createdAt: table.createdAt,
updatedAt: table.updatedAt,
}
}

Expand All @@ -145,7 +159,10 @@ export const toSigningDriverConfig = (
): SigningDriverConfig => {
return {
driverId: table.driverId,
config: JSON.parse(table.config),
config:
typeof table.config === 'string'
? JSON.parse(table.config)
: table.config,
}
}

Expand Down
26 changes: 16 additions & 10 deletions core/signing-store-sql/src/store-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
SigningDriverStatus,
SigningDriverConfig,
} from '@canton-network/core-signing-lib'
import { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely'
import { CamelCasePlugin, Kysely, SqliteDialect, PostgresDialect } from 'kysely'
import { Pool } from 'pg'
import Database from 'better-sqlite3'
import {
DB,
Expand Down Expand Up @@ -191,11 +192,7 @@ export class StoreSql implements SigningDriverStore, AuthAware<StoreSql> {
if (before) {
const beforeTx = await this.getSigningTransaction(userId, before)
if (beforeTx) {
query = query.where(
'createdAt',
'<',
beforeTx.createdAt.toISOString()
)
query = query.where('createdAt', '<', beforeTx.createdAt)
}
}

Expand Down Expand Up @@ -308,16 +305,25 @@ export const connection = (config: StoreConfig) => {
}),
plugins: [new CamelCasePlugin()],
})
case 'postgres':
return new Kysely<DB>({
dialect: new PostgresDialect({
pool: new Pool({
database: config.connection.database,
user: config.connection.user,
password: config.connection.password,
port: config.connection.port,
host: config.connection.host,
}),
}),
plugins: [new CamelCasePlugin()],
})
case 'memory':
return new Kysely<DB>({
dialect: new SqliteDialect({
database: new Database(':memory:'),
}),
plugins: [new CamelCasePlugin()],
})
default:
throw new Error(
`Unsupported database type: ${config.connection.type}`
)
}
}
2 changes: 2 additions & 0 deletions core/wallet-store-sql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"better-sqlite3": "^12.2.0",
"commander": "^14.0.0",
"kysely": "^0.28.5",
"pg": "^8.16.3",
"pino": "^10.0.0",
"umzug": "^3.8.2",
"zod": "^3.25.64"
Expand All @@ -43,6 +44,7 @@
"@swc/jest": "^0.2.38",
"@types/better-sqlite3": "^7.6.13",
"@types/jest": "^30.0.0",
"@types/pg": "^8",
"jest": "^30.0.0",
"pino-test": "^1.1.0",
"ts-jest": "^29.4.0",
Expand Down
12 changes: 9 additions & 3 deletions core/wallet-store-sql/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,15 @@ export const toNetwork = (table: NetworkTable): Network => {
ledgerApi: {
baseUrl: table.ledgerApiBaseUrl,
},
auth: authSchema.parse(JSON.parse(table.auth)),
auth: authSchema.parse(
typeof table.auth === 'string' ? JSON.parse(table.auth) : table.auth
),
adminAuth: table.adminAuth
? authSchema.parse(JSON.parse(table.adminAuth))
? authSchema.parse(
typeof table.adminAuth === 'string'
? JSON.parse(table.adminAuth)
: table.adminAuth
)
: undefined,
}
}
Expand Down Expand Up @@ -159,7 +165,7 @@ export const fromWallet = (wallet: Wallet, userId: UserId): WalletTable => {
export const toWallet = (table: WalletTable): Wallet => {
return {
...table,
primary: table.primary === 1,
primary: Boolean(table.primary),
}
}

Expand Down
20 changes: 15 additions & 5 deletions core/wallet-store-sql/src/store-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
StoreConfig,
UpdateWallet,
} from '@canton-network/core-wallet-store'
import { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely'
import { CamelCasePlugin, Kysely, PostgresDialect, SqliteDialect } from 'kysely'
import Database from 'better-sqlite3'
import {
DB,
Expand All @@ -33,6 +33,7 @@ import {
toTransaction,
toWallet,
} from './schema.js'
import { Pool } from 'pg'

export class StoreSql implements BaseStore, AuthAware<StoreSql> {
authContext: AuthContext | undefined
Expand Down Expand Up @@ -440,16 +441,25 @@ export const connection = (config: StoreConfig) => {
}),
plugins: [new CamelCasePlugin()],
})
case 'postgres':
return new Kysely<DB>({
dialect: new PostgresDialect({
pool: new Pool({
database: config.connection.database,
user: config.connection.user,
password: config.connection.password,
port: config.connection.port,
host: config.connection.host,
}),
}),
plugins: [new CamelCasePlugin()],
})
case 'memory':
return new Kysely<DB>({
dialect: new SqliteDialect({
database: new Database(':memory:'),
}),
plugins: [new CamelCasePlugin()],
})
default:
throw new Error(
`Unsupported database type: ${config.connection.type}`
)
}
}
37 changes: 37 additions & 0 deletions wallet-gateway/remote/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,40 @@ The JSON-RPC API specs from `api-specs/` are generated into strongly-typed metho
2. Place the `fireblocks_secret.key` file at the path `/splice-wallet-kernel/wallet-gateway/remote`

3. Create a file named `fireblocks_api.key` at the path `/splice-wallet-kernel/wallet-gateway/remote` and insert your Fireblocks API key into it

## Postgres connection

To create a Postgres database you need to:

1. Start Postgres in Docker using:

```shell
$ docker run --network=host --name some-postgres -e POSTGRES_PASSWORD=postgres -d postgres
```

2. In the file `splice-wallet-kernel/wallet-gateway/test/config.json`, specify the connection settings for both databases (store and signingStore). The connection should look like this (it is important that `store.connection.database !== signingStore.connection.database !== 'postgres'`):

```json
{
"store": {
"connection": {
"type": "postgres",
"password": "postgres",
"port": 5432,
"user": "postgres",
"host": "0.0.0.0",
"database": "wallet_store"
}
},
"signingStore": {
"connection": {
"type": "postgres",
"password": "postgres",
"port": 5432,
"user": "postgres",
"host": "0.0.0.0",
"database": "signing_store"
}
}
}
```
1 change: 1 addition & 0 deletions wallet-gateway/remote/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"express": "^5.1.0",
"express-rate-limit": "^7.5.1",
"jose": "^5.10.0",
"kysely": "^0.28.5",
"lit": "^3.3.0",
"pino": "^9.7.0",
"pino-pretty": "^13.0.0",
Expand Down
Loading
Loading