@waiaas/daemon 2.11.0-rc → 2.11.0-rc.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/middleware/resolve-asset.d.ts +26 -0
- package/dist/api/middleware/resolve-asset.d.ts.map +1 -0
- package/dist/api/middleware/resolve-asset.js +81 -0
- package/dist/api/middleware/resolve-asset.js.map +1 -0
- package/dist/api/routes/actions.d.ts +4 -0
- package/dist/api/routes/actions.d.ts.map +1 -1
- package/dist/api/routes/actions.js +120 -0
- package/dist/api/routes/actions.js.map +1 -1
- package/dist/api/routes/admin-auth.d.ts.map +1 -1
- package/dist/api/routes/admin-auth.js +4 -1
- package/dist/api/routes/admin-auth.js.map +1 -1
- package/dist/api/routes/admin-credentials.d.ts +20 -0
- package/dist/api/routes/admin-credentials.d.ts.map +1 -0
- package/dist/api/routes/admin-credentials.js +115 -0
- package/dist/api/routes/admin-credentials.js.map +1 -0
- package/dist/api/routes/admin-settings.d.ts.map +1 -1
- package/dist/api/routes/admin-settings.js +70 -1
- package/dist/api/routes/admin-settings.js.map +1 -1
- package/dist/api/routes/admin-wallets.d.ts.map +1 -1
- package/dist/api/routes/admin-wallets.js +27 -14
- package/dist/api/routes/admin-wallets.js.map +1 -1
- package/dist/api/routes/connect-info.d.ts +2 -0
- package/dist/api/routes/connect-info.d.ts.map +1 -1
- package/dist/api/routes/connect-info.js +32 -1
- package/dist/api/routes/connect-info.js.map +1 -1
- package/dist/api/routes/credentials.d.ts +20 -0
- package/dist/api/routes/credentials.d.ts.map +1 -0
- package/dist/api/routes/credentials.js +120 -0
- package/dist/api/routes/credentials.js.map +1 -0
- package/dist/api/routes/defi-positions.d.ts.map +1 -1
- package/dist/api/routes/defi-positions.js +10 -0
- package/dist/api/routes/defi-positions.js.map +1 -1
- package/dist/api/routes/external-actions.d.ts +19 -0
- package/dist/api/routes/external-actions.d.ts.map +1 -0
- package/dist/api/routes/external-actions.js +199 -0
- package/dist/api/routes/external-actions.js.map +1 -0
- package/dist/api/routes/incoming.d.ts.map +1 -1
- package/dist/api/routes/incoming.js +2 -1
- package/dist/api/routes/incoming.js.map +1 -1
- package/dist/api/routes/index.d.ts +3 -0
- package/dist/api/routes/index.d.ts.map +1 -1
- package/dist/api/routes/index.js +3 -0
- package/dist/api/routes/index.js.map +1 -1
- package/dist/api/routes/nfts.js +24 -4
- package/dist/api/routes/nfts.js.map +1 -1
- package/dist/api/routes/openapi-schemas.d.ts +321 -139
- package/dist/api/routes/openapi-schemas.d.ts.map +1 -1
- package/dist/api/routes/openapi-schemas.js +24 -0
- package/dist/api/routes/openapi-schemas.js.map +1 -1
- package/dist/api/routes/rpc-proxy.d.ts +55 -0
- package/dist/api/routes/rpc-proxy.d.ts.map +1 -0
- package/dist/api/routes/rpc-proxy.js +285 -0
- package/dist/api/routes/rpc-proxy.js.map +1 -0
- package/dist/api/routes/staking.d.ts.map +1 -1
- package/dist/api/routes/staking.js +15 -0
- package/dist/api/routes/staking.js.map +1 -1
- package/dist/api/routes/tokens.d.ts.map +1 -1
- package/dist/api/routes/tokens.js +8 -1
- package/dist/api/routes/tokens.js.map +1 -1
- package/dist/api/routes/transactions.d.ts +35 -0
- package/dist/api/routes/transactions.d.ts.map +1 -1
- package/dist/api/routes/transactions.js +220 -20
- package/dist/api/routes/transactions.js.map +1 -1
- package/dist/api/routes/wallet.d.ts.map +1 -1
- package/dist/api/routes/wallet.js +18 -4
- package/dist/api/routes/wallet.js.map +1 -1
- package/dist/api/server.d.ts +2 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +52 -1
- package/dist/api/server.js.map +1 -1
- package/dist/infrastructure/action/action-provider-registry.d.ts.map +1 -1
- package/dist/infrastructure/action/action-provider-registry.js +12 -0
- package/dist/infrastructure/action/action-provider-registry.js.map +1 -1
- package/dist/infrastructure/credential/credential-crypto.d.ts +43 -0
- package/dist/infrastructure/credential/credential-crypto.d.ts.map +1 -0
- package/dist/infrastructure/credential/credential-crypto.js +64 -0
- package/dist/infrastructure/credential/credential-crypto.js.map +1 -0
- package/dist/infrastructure/credential/credential-vault.d.ts +42 -0
- package/dist/infrastructure/credential/credential-vault.d.ts.map +1 -0
- package/dist/infrastructure/credential/credential-vault.js +235 -0
- package/dist/infrastructure/credential/credential-vault.js.map +1 -0
- package/dist/infrastructure/credential/index.d.ts +6 -0
- package/dist/infrastructure/credential/index.d.ts.map +1 -0
- package/dist/infrastructure/credential/index.js +6 -0
- package/dist/infrastructure/credential/index.js.map +1 -0
- package/dist/infrastructure/database/migrate.d.ts +1 -1
- package/dist/infrastructure/database/migrate.d.ts.map +1 -1
- package/dist/infrastructure/database/migrate.js +191 -6
- package/dist/infrastructure/database/migrate.js.map +1 -1
- package/dist/infrastructure/database/schema.d.ts +281 -1
- package/dist/infrastructure/database/schema.d.ts.map +1 -1
- package/dist/infrastructure/database/schema.js +34 -3
- package/dist/infrastructure/database/schema.js.map +1 -1
- package/dist/infrastructure/keystore/re-encrypt.d.ts +9 -0
- package/dist/infrastructure/keystore/re-encrypt.d.ts.map +1 -1
- package/dist/infrastructure/keystore/re-encrypt.js +47 -1
- package/dist/infrastructure/keystore/re-encrypt.js.map +1 -1
- package/dist/infrastructure/settings/index.d.ts +2 -2
- package/dist/infrastructure/settings/index.d.ts.map +1 -1
- package/dist/infrastructure/settings/index.js +1 -1
- package/dist/infrastructure/settings/index.js.map +1 -1
- package/dist/infrastructure/settings/setting-keys.d.ts +16 -2
- package/dist/infrastructure/settings/setting-keys.d.ts.map +1 -1
- package/dist/infrastructure/settings/setting-keys.js +296 -206
- package/dist/infrastructure/settings/setting-keys.js.map +1 -1
- package/dist/lifecycle/daemon.d.ts.map +1 -1
- package/dist/lifecycle/daemon.js +31 -0
- package/dist/lifecycle/daemon.js.map +1 -1
- package/dist/notifications/templates/message-templates.d.ts.map +1 -1
- package/dist/notifications/templates/message-templates.js +5 -6
- package/dist/notifications/templates/message-templates.js.map +1 -1
- package/dist/pipeline/database-policy-engine.d.ts +36 -0
- package/dist/pipeline/database-policy-engine.d.ts.map +1 -1
- package/dist/pipeline/database-policy-engine.js +185 -0
- package/dist/pipeline/database-policy-engine.js.map +1 -1
- package/dist/pipeline/external-action-pipeline.d.ts +64 -0
- package/dist/pipeline/external-action-pipeline.d.ts.map +1 -0
- package/dist/pipeline/external-action-pipeline.js +427 -0
- package/dist/pipeline/external-action-pipeline.js.map +1 -0
- package/dist/pipeline/pipeline.d.ts +4 -0
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/resolve-effective-amount-usd.d.ts.map +1 -1
- package/dist/pipeline/resolve-effective-amount-usd.js +2 -1
- package/dist/pipeline/resolve-effective-amount-usd.js.map +1 -1
- package/dist/pipeline/stages.d.ts.map +1 -1
- package/dist/pipeline/stages.js +59 -10
- package/dist/pipeline/stages.js.map +1 -1
- package/dist/rpc-proxy/completion-waiter.d.ts +35 -0
- package/dist/rpc-proxy/completion-waiter.d.ts.map +1 -0
- package/dist/rpc-proxy/completion-waiter.js +72 -0
- package/dist/rpc-proxy/completion-waiter.js.map +1 -0
- package/dist/rpc-proxy/dispatcher.d.ts +37 -0
- package/dist/rpc-proxy/dispatcher.d.ts.map +1 -0
- package/dist/rpc-proxy/dispatcher.js +54 -0
- package/dist/rpc-proxy/dispatcher.js.map +1 -0
- package/dist/rpc-proxy/index.d.ts +15 -0
- package/dist/rpc-proxy/index.d.ts.map +1 -0
- package/dist/rpc-proxy/index.js +15 -0
- package/dist/rpc-proxy/index.js.map +1 -0
- package/dist/rpc-proxy/json-rpc.d.ts +78 -0
- package/dist/rpc-proxy/json-rpc.d.ts.map +1 -0
- package/dist/rpc-proxy/json-rpc.js +123 -0
- package/dist/rpc-proxy/json-rpc.js.map +1 -0
- package/dist/rpc-proxy/method-handlers.d.ts +54 -0
- package/dist/rpc-proxy/method-handlers.d.ts.map +1 -0
- package/dist/rpc-proxy/method-handlers.js +171 -0
- package/dist/rpc-proxy/method-handlers.js.map +1 -0
- package/dist/rpc-proxy/nonce-tracker.d.ts +39 -0
- package/dist/rpc-proxy/nonce-tracker.d.ts.map +1 -0
- package/dist/rpc-proxy/nonce-tracker.js +80 -0
- package/dist/rpc-proxy/nonce-tracker.js.map +1 -0
- package/dist/rpc-proxy/passthrough.d.ts +37 -0
- package/dist/rpc-proxy/passthrough.d.ts.map +1 -0
- package/dist/rpc-proxy/passthrough.js +86 -0
- package/dist/rpc-proxy/passthrough.js.map +1 -0
- package/dist/rpc-proxy/sync-pipeline.d.ts +40 -0
- package/dist/rpc-proxy/sync-pipeline.d.ts.map +1 -0
- package/dist/rpc-proxy/sync-pipeline.js +74 -0
- package/dist/rpc-proxy/sync-pipeline.js.map +1 -0
- package/dist/rpc-proxy/tx-adapter.d.ts +79 -0
- package/dist/rpc-proxy/tx-adapter.d.ts.map +1 -0
- package/dist/rpc-proxy/tx-adapter.js +117 -0
- package/dist/rpc-proxy/tx-adapter.js.map +1 -0
- package/dist/services/async-polling-service.d.ts.map +1 -1
- package/dist/services/async-polling-service.js +95 -2
- package/dist/services/async-polling-service.js.map +1 -1
- package/dist/signing/bootstrap.d.ts +12 -0
- package/dist/signing/bootstrap.d.ts.map +1 -0
- package/dist/signing/bootstrap.js +15 -0
- package/dist/signing/bootstrap.js.map +1 -0
- package/dist/signing/capabilities/ecdsa-signer.d.ts +7 -0
- package/dist/signing/capabilities/ecdsa-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/ecdsa-signer.js +42 -0
- package/dist/signing/capabilities/ecdsa-signer.js.map +1 -0
- package/dist/signing/capabilities/ed25519-signer.d.ts +7 -0
- package/dist/signing/capabilities/ed25519-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/ed25519-signer.js +39 -0
- package/dist/signing/capabilities/ed25519-signer.js.map +1 -0
- package/dist/signing/capabilities/eip712-signer.d.ts +7 -0
- package/dist/signing/capabilities/eip712-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/eip712-signer.js +35 -0
- package/dist/signing/capabilities/eip712-signer.js.map +1 -0
- package/dist/signing/capabilities/erc8128-signer.d.ts +7 -0
- package/dist/signing/capabilities/erc8128-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/erc8128-signer.js +55 -0
- package/dist/signing/capabilities/erc8128-signer.js.map +1 -0
- package/dist/signing/capabilities/hmac-signer.d.ts +7 -0
- package/dist/signing/capabilities/hmac-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/hmac-signer.js +32 -0
- package/dist/signing/capabilities/hmac-signer.js.map +1 -0
- package/dist/signing/capabilities/index.d.ts +13 -0
- package/dist/signing/capabilities/index.d.ts.map +1 -0
- package/dist/signing/capabilities/index.js +13 -0
- package/dist/signing/capabilities/index.js.map +1 -0
- package/dist/signing/capabilities/personal-signer.d.ts +7 -0
- package/dist/signing/capabilities/personal-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/personal-signer.js +35 -0
- package/dist/signing/capabilities/personal-signer.js.map +1 -0
- package/dist/signing/capabilities/rsa-pss-signer.d.ts +7 -0
- package/dist/signing/capabilities/rsa-pss-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/rsa-pss-signer.js +35 -0
- package/dist/signing/capabilities/rsa-pss-signer.js.map +1 -0
- package/dist/signing/index.d.ts +13 -0
- package/dist/signing/index.d.ts.map +1 -0
- package/dist/signing/index.js +5 -0
- package/dist/signing/index.js.map +1 -0
- package/dist/signing/registry.d.ts +36 -0
- package/dist/signing/registry.d.ts.map +1 -0
- package/dist/signing/registry.js +27 -0
- package/dist/signing/registry.js.map +1 -0
- package/dist/signing/signing-error.d.ts +22 -0
- package/dist/signing/signing-error.d.ts.map +1 -0
- package/dist/signing/signing-error.js +17 -0
- package/dist/signing/signing-error.js.map +1 -0
- package/dist/signing/types.d.ts +91 -0
- package/dist/signing/types.d.ts.map +1 -0
- package/dist/signing/types.js +2 -0
- package/dist/signing/types.js.map +1 -0
- package/package.json +6 -5
- package/public/admin/assets/index-COymjGTe.js +3 -0
- package/public/admin/assets/index-CTHU1J8K.css +1 -0
- package/public/admin/index.html +4 -2
- package/public/admin/assets/index-BpDnuS0k.css +0 -1
- package/public/admin/assets/index-By5VUJ-B.js +0 -3
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential Vault -- secure encrypted storage for external service credentials.
|
|
3
|
+
*
|
|
4
|
+
* ICredentialVault defines the interface for credential CRUD operations.
|
|
5
|
+
* LocalCredentialVault implements it using the local SQLite database with
|
|
6
|
+
* AES-256-GCM encryption (HKDF-derived key from master password).
|
|
7
|
+
*
|
|
8
|
+
* Resolution priority for name-based lookup:
|
|
9
|
+
* 1. Per-wallet credential (walletId + name match)
|
|
10
|
+
* 2. Global credential (walletId IS NULL + name match)
|
|
11
|
+
*
|
|
12
|
+
* @see docs/81-external-action-design.md D3.6 CredentialVault
|
|
13
|
+
*/
|
|
14
|
+
import { eq, and, isNull } from 'drizzle-orm';
|
|
15
|
+
import { WAIaaSError } from '@waiaas/core';
|
|
16
|
+
import { walletCredentials } from '../database/schema.js';
|
|
17
|
+
import { generateId } from '../database/id.js';
|
|
18
|
+
import { encryptCredential, decryptCredential } from './credential-crypto.js';
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Implementation
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// UUID v7 regex (loose): 8-4-4-4-12 hex groups
|
|
23
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24
|
+
/**
|
|
25
|
+
* Build AAD string for a credential row.
|
|
26
|
+
* Format: "{id}:{walletId|global}:{type}"
|
|
27
|
+
*/
|
|
28
|
+
function buildAad(id, walletId, type) {
|
|
29
|
+
return `${id}:${walletId ?? 'global'}:${type}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convert a DB row to CredentialMetadata (without value).
|
|
33
|
+
*/
|
|
34
|
+
function toMetadata(row) {
|
|
35
|
+
return {
|
|
36
|
+
id: row.id,
|
|
37
|
+
walletId: row.walletId,
|
|
38
|
+
type: row.type,
|
|
39
|
+
name: row.name,
|
|
40
|
+
metadata: JSON.parse(row.metadata),
|
|
41
|
+
expiresAt: row.expiresAt,
|
|
42
|
+
createdAt: row.createdAt instanceof Date
|
|
43
|
+
? Math.floor(row.createdAt.getTime() / 1000)
|
|
44
|
+
: row.createdAt,
|
|
45
|
+
updatedAt: row.updatedAt instanceof Date
|
|
46
|
+
? Math.floor(row.updatedAt.getTime() / 1000)
|
|
47
|
+
: row.updatedAt,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export class LocalCredentialVault {
|
|
51
|
+
db;
|
|
52
|
+
getMasterPassword;
|
|
53
|
+
constructor(db, getMasterPassword) {
|
|
54
|
+
this.db = db;
|
|
55
|
+
this.getMasterPassword = getMasterPassword;
|
|
56
|
+
}
|
|
57
|
+
// -----------------------------------------------------------------------
|
|
58
|
+
// create
|
|
59
|
+
// -----------------------------------------------------------------------
|
|
60
|
+
async create(walletId, params) {
|
|
61
|
+
// Check for duplicate name in same scope
|
|
62
|
+
// (SQLite NULL != NULL for unique indexes, so global duplicates need manual check)
|
|
63
|
+
const existingCondition = walletId
|
|
64
|
+
? and(eq(walletCredentials.walletId, walletId), eq(walletCredentials.name, params.name))
|
|
65
|
+
: and(isNull(walletCredentials.walletId), eq(walletCredentials.name, params.name));
|
|
66
|
+
const existing = this.db.select().from(walletCredentials).where(existingCondition).get();
|
|
67
|
+
if (existing) {
|
|
68
|
+
throw new WAIaaSError('ACTION_VALIDATION_FAILED', {
|
|
69
|
+
message: `Credential with name "${params.name}" already exists for this scope`,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const id = generateId();
|
|
73
|
+
const masterPassword = this.getMasterPassword();
|
|
74
|
+
const aad = buildAad(id, walletId, params.type);
|
|
75
|
+
const encrypted = encryptCredential(params.value, masterPassword, aad);
|
|
76
|
+
const now = new Date();
|
|
77
|
+
try {
|
|
78
|
+
this.db
|
|
79
|
+
.insert(walletCredentials)
|
|
80
|
+
.values({
|
|
81
|
+
id,
|
|
82
|
+
walletId,
|
|
83
|
+
type: params.type,
|
|
84
|
+
name: params.name,
|
|
85
|
+
encryptedValue: encrypted.encryptedValue,
|
|
86
|
+
iv: encrypted.iv,
|
|
87
|
+
authTag: encrypted.authTag,
|
|
88
|
+
metadata: JSON.stringify(params.metadata ?? {}),
|
|
89
|
+
expiresAt: params.expiresAt ?? null,
|
|
90
|
+
createdAt: now,
|
|
91
|
+
updatedAt: now,
|
|
92
|
+
})
|
|
93
|
+
.run();
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
// SQLite UNIQUE constraint violation (belt-and-suspenders after pre-check above)
|
|
97
|
+
if (err instanceof Error && err.message.includes('UNIQUE constraint failed')) {
|
|
98
|
+
throw new WAIaaSError('ACTION_VALIDATION_FAILED', {
|
|
99
|
+
message: `Credential with name "${params.name}" already exists for this scope`,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
id,
|
|
106
|
+
walletId,
|
|
107
|
+
type: params.type,
|
|
108
|
+
name: params.name,
|
|
109
|
+
metadata: params.metadata ?? {},
|
|
110
|
+
expiresAt: params.expiresAt ?? null,
|
|
111
|
+
createdAt: Math.floor(now.getTime() / 1000),
|
|
112
|
+
updatedAt: Math.floor(now.getTime() / 1000),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// -----------------------------------------------------------------------
|
|
116
|
+
// get
|
|
117
|
+
// -----------------------------------------------------------------------
|
|
118
|
+
async get(ref, walletId) {
|
|
119
|
+
const row = await this.resolveRow(ref, walletId);
|
|
120
|
+
// Check expiry
|
|
121
|
+
if (row.expiresAt !== null) {
|
|
122
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
123
|
+
if (row.expiresAt < nowSec) {
|
|
124
|
+
throw new WAIaaSError('CREDENTIAL_EXPIRED', {
|
|
125
|
+
message: `Credential "${row.name}" has expired`,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const masterPassword = this.getMasterPassword();
|
|
130
|
+
const aad = buildAad(row.id, row.walletId, row.type);
|
|
131
|
+
const value = decryptCredential({
|
|
132
|
+
encryptedValue: row.encryptedValue,
|
|
133
|
+
iv: row.iv,
|
|
134
|
+
authTag: row.authTag,
|
|
135
|
+
}, masterPassword, aad);
|
|
136
|
+
return {
|
|
137
|
+
...toMetadata(row),
|
|
138
|
+
value,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// -----------------------------------------------------------------------
|
|
142
|
+
// list
|
|
143
|
+
// -----------------------------------------------------------------------
|
|
144
|
+
async list(walletId) {
|
|
145
|
+
const condition = walletId
|
|
146
|
+
? eq(walletCredentials.walletId, walletId)
|
|
147
|
+
: isNull(walletCredentials.walletId);
|
|
148
|
+
const rows = this.db
|
|
149
|
+
.select()
|
|
150
|
+
.from(walletCredentials)
|
|
151
|
+
.where(condition)
|
|
152
|
+
.all();
|
|
153
|
+
return rows.map(toMetadata);
|
|
154
|
+
}
|
|
155
|
+
// -----------------------------------------------------------------------
|
|
156
|
+
// delete
|
|
157
|
+
// -----------------------------------------------------------------------
|
|
158
|
+
async delete(ref) {
|
|
159
|
+
const row = await this.resolveRow(ref);
|
|
160
|
+
this.db.delete(walletCredentials).where(eq(walletCredentials.id, row.id)).run();
|
|
161
|
+
}
|
|
162
|
+
// -----------------------------------------------------------------------
|
|
163
|
+
// rotate
|
|
164
|
+
// -----------------------------------------------------------------------
|
|
165
|
+
async rotate(ref, newValue) {
|
|
166
|
+
const row = await this.resolveRow(ref);
|
|
167
|
+
const masterPassword = this.getMasterPassword();
|
|
168
|
+
const aad = buildAad(row.id, row.walletId, row.type);
|
|
169
|
+
const encrypted = encryptCredential(newValue, masterPassword, aad);
|
|
170
|
+
const now = new Date();
|
|
171
|
+
this.db
|
|
172
|
+
.update(walletCredentials)
|
|
173
|
+
.set({
|
|
174
|
+
encryptedValue: encrypted.encryptedValue,
|
|
175
|
+
iv: encrypted.iv,
|
|
176
|
+
authTag: encrypted.authTag,
|
|
177
|
+
updatedAt: now,
|
|
178
|
+
})
|
|
179
|
+
.where(eq(walletCredentials.id, row.id))
|
|
180
|
+
.run();
|
|
181
|
+
return {
|
|
182
|
+
...toMetadata(row),
|
|
183
|
+
updatedAt: Math.floor(now.getTime() / 1000),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
// -----------------------------------------------------------------------
|
|
187
|
+
// Internal helpers
|
|
188
|
+
// -----------------------------------------------------------------------
|
|
189
|
+
/**
|
|
190
|
+
* Resolve a credential reference to a DB row.
|
|
191
|
+
*
|
|
192
|
+
* Reference formats:
|
|
193
|
+
* 1. UUID (direct lookup)
|
|
194
|
+
* 2. Name string (per-wallet priority, then global fallback)
|
|
195
|
+
*/
|
|
196
|
+
async resolveRow(ref, walletId) {
|
|
197
|
+
// 1. UUID direct lookup
|
|
198
|
+
if (UUID_RE.test(ref)) {
|
|
199
|
+
const row = this.db
|
|
200
|
+
.select()
|
|
201
|
+
.from(walletCredentials)
|
|
202
|
+
.where(eq(walletCredentials.id, ref))
|
|
203
|
+
.get();
|
|
204
|
+
if (!row) {
|
|
205
|
+
throw new WAIaaSError('CREDENTIAL_NOT_FOUND', {
|
|
206
|
+
message: `Credential not found: ${ref}`,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return row;
|
|
210
|
+
}
|
|
211
|
+
// 2. Name-based resolution with per-wallet priority
|
|
212
|
+
if (walletId) {
|
|
213
|
+
// Try per-wallet first
|
|
214
|
+
const perWallet = this.db
|
|
215
|
+
.select()
|
|
216
|
+
.from(walletCredentials)
|
|
217
|
+
.where(and(eq(walletCredentials.walletId, walletId), eq(walletCredentials.name, ref)))
|
|
218
|
+
.get();
|
|
219
|
+
if (perWallet)
|
|
220
|
+
return perWallet;
|
|
221
|
+
}
|
|
222
|
+
// Try global fallback
|
|
223
|
+
const global = this.db
|
|
224
|
+
.select()
|
|
225
|
+
.from(walletCredentials)
|
|
226
|
+
.where(and(isNull(walletCredentials.walletId), eq(walletCredentials.name, ref)))
|
|
227
|
+
.get();
|
|
228
|
+
if (global)
|
|
229
|
+
return global;
|
|
230
|
+
throw new WAIaaSError('CREDENTIAL_NOT_FOUND', {
|
|
231
|
+
message: `Credential not found: ${ref}`,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=credential-vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-vault.js","sourceRoot":"","sources":["../../../src/infrastructure/credential/credential-vault.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential vault module barrel export.
|
|
3
|
+
*/
|
|
4
|
+
export { deriveCredentialKey, encryptCredential, decryptCredential, type EncryptedCredentialData, } from './credential-crypto.js';
|
|
5
|
+
export { type ICredentialVault, LocalCredentialVault, } from './credential-vault.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/credential/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,uBAAuB,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/credential/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,oBAAoB,GACrB,MAAM,uBAAuB,CAAC"}
|
|
@@ -28,7 +28,7 @@ import type { Database } from 'better-sqlite3';
|
|
|
28
28
|
* pushSchema() records this version for fresh databases so migrations are skipped.
|
|
29
29
|
* Increment this whenever DDL statements are updated to match a new migration.
|
|
30
30
|
*/
|
|
31
|
-
export declare const LATEST_SCHEMA_VERSION =
|
|
31
|
+
export declare const LATEST_SCHEMA_VERSION = 58;
|
|
32
32
|
/** A single incremental migration (ALTER TABLE, CREATE INDEX, etc.). */
|
|
33
33
|
export interface Migration {
|
|
34
34
|
/** Monotonically increasing version number (must be > 1, since version 1 = initial schema). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/database/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAmD/C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/database/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAmD/C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AA4mBxC,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2FAA2F;IAC3F,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,EAAO,CAAC;AAghF1C;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,EAChB,UAAU,GAAE,SAAS,EAAe,GACnC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgFtC;AAMD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAsGjD"}
|
|
@@ -47,14 +47,14 @@ const LEGACY_NETWORK_NORMALIZE = {
|
|
|
47
47
|
testnet: 'solana-testnet',
|
|
48
48
|
};
|
|
49
49
|
// ---------------------------------------------------------------------------
|
|
50
|
-
// DDL statements for all
|
|
50
|
+
// DDL statements for all 31 tables (latest schema: wallets + wallet_id + session_wallets + token_registry + settings + telegram_users + wc_sessions + wc_store + incoming_transactions + incoming_tx_cursors + defi_positions + wallet_apps + webhooks + webhook_logs + agent_identities + reputation_cache + nft_metadata_cache + userop_builds + hyperliquid_orders + hyperliquid_sub_accounts + polymarket_orders + polymarket_positions + polymarket_api_keys + wallet_credentials)
|
|
51
51
|
// ---------------------------------------------------------------------------
|
|
52
52
|
/**
|
|
53
53
|
* The latest schema version that getCreateTableStatements() represents.
|
|
54
54
|
* pushSchema() records this version for fresh databases so migrations are skipped.
|
|
55
55
|
* Increment this whenever DDL statements are updated to match a new migration.
|
|
56
56
|
*/
|
|
57
|
-
export const LATEST_SCHEMA_VERSION =
|
|
57
|
+
export const LATEST_SCHEMA_VERSION = 58;
|
|
58
58
|
function getCreateTableStatements() {
|
|
59
59
|
return [
|
|
60
60
|
// Table 1: wallets (renamed from agents in v3, environment model in v6b, v29.3: default_network removed)
|
|
@@ -136,8 +136,12 @@ function getCreateTableStatements() {
|
|
|
136
136
|
error TEXT,
|
|
137
137
|
metadata TEXT,
|
|
138
138
|
network TEXT CHECK (network IS NULL OR network IN (${inList(NETWORK_TYPES)})),
|
|
139
|
-
bridge_status TEXT CHECK (bridge_status IS NULL OR bridge_status IN ('PENDING', 'COMPLETED', 'FAILED', 'BRIDGE_MONITORING', 'TIMEOUT', 'REFUNDED')),
|
|
140
|
-
bridge_metadata TEXT
|
|
139
|
+
bridge_status TEXT CHECK (bridge_status IS NULL OR bridge_status IN ('PENDING', 'COMPLETED', 'FAILED', 'BRIDGE_MONITORING', 'TIMEOUT', 'REFUNDED', 'PARTIALLY_FILLED', 'FILLED', 'CANCELED', 'SETTLED', 'EXPIRED')),
|
|
140
|
+
bridge_metadata TEXT,
|
|
141
|
+
action_kind TEXT NOT NULL DEFAULT 'contractCall',
|
|
142
|
+
venue TEXT,
|
|
143
|
+
operation TEXT,
|
|
144
|
+
external_id TEXT
|
|
141
145
|
)`,
|
|
142
146
|
// Table 4: policies (network column added in v8)
|
|
143
147
|
`CREATE TABLE IF NOT EXISTS policies (
|
|
@@ -472,6 +476,21 @@ function getCreateTableStatements() {
|
|
|
472
476
|
proxy_address TEXT,
|
|
473
477
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
474
478
|
UNIQUE(wallet_id)
|
|
479
|
+
)`,
|
|
480
|
+
// Table 31: wallet_credentials (External Action credential vault, v55)
|
|
481
|
+
`CREATE TABLE IF NOT EXISTS wallet_credentials (
|
|
482
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
483
|
+
wallet_id TEXT,
|
|
484
|
+
type TEXT NOT NULL CHECK (type IN ('api-key','hmac-secret','rsa-private-key','session-token','custom')),
|
|
485
|
+
name TEXT NOT NULL,
|
|
486
|
+
encrypted_value BLOB NOT NULL,
|
|
487
|
+
iv BLOB NOT NULL,
|
|
488
|
+
auth_tag BLOB NOT NULL,
|
|
489
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
490
|
+
expires_at INTEGER,
|
|
491
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
492
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
493
|
+
FOREIGN KEY (wallet_id) REFERENCES wallets(id) ON DELETE CASCADE
|
|
475
494
|
)`,
|
|
476
495
|
];
|
|
477
496
|
}
|
|
@@ -577,6 +596,17 @@ function getCreateIndexStatements() {
|
|
|
577
596
|
'CREATE INDEX IF NOT EXISTS idx_pm_positions_condition ON polymarket_positions(condition_id)',
|
|
578
597
|
'CREATE INDEX IF NOT EXISTS idx_pm_positions_resolved ON polymarket_positions(market_resolved)',
|
|
579
598
|
// v54: polymarket_api_keys indexes (UNIQUE on wallet_id is inline)
|
|
599
|
+
// v55: wallet_credentials indexes
|
|
600
|
+
'CREATE UNIQUE INDEX IF NOT EXISTS idx_wallet_credentials_wallet_name ON wallet_credentials(wallet_id, name)',
|
|
601
|
+
'CREATE INDEX IF NOT EXISTS idx_wallet_credentials_global_name ON wallet_credentials(name) WHERE wallet_id IS NULL',
|
|
602
|
+
'CREATE INDEX IF NOT EXISTS idx_wallet_credentials_wallet_id ON wallet_credentials(wallet_id)',
|
|
603
|
+
'CREATE INDEX IF NOT EXISTS idx_wallet_credentials_expires_at ON wallet_credentials(expires_at) WHERE expires_at IS NOT NULL',
|
|
604
|
+
// v56: transactions action tracking indexes
|
|
605
|
+
'CREATE INDEX IF NOT EXISTS idx_transactions_action_kind ON transactions(action_kind)',
|
|
606
|
+
'CREATE INDEX IF NOT EXISTS idx_transactions_venue ON transactions(venue) WHERE venue IS NOT NULL',
|
|
607
|
+
'CREATE INDEX IF NOT EXISTS idx_transactions_external_id ON transactions(external_id) WHERE external_id IS NOT NULL',
|
|
608
|
+
// v57: composite index for external action tracking queries
|
|
609
|
+
'CREATE INDEX IF NOT EXISTS idx_transactions_action_kind_bridge_status ON transactions(action_kind, bridge_status) WHERE bridge_status IS NOT NULL',
|
|
580
610
|
];
|
|
581
611
|
}
|
|
582
612
|
/**
|
|
@@ -1659,7 +1689,7 @@ MIGRATIONS.push({
|
|
|
1659
1689
|
error TEXT,
|
|
1660
1690
|
metadata TEXT,
|
|
1661
1691
|
network TEXT CHECK (network IS NULL OR network IN (${inList(NETWORK_TYPES_WITH_LEGACY)})),
|
|
1662
|
-
bridge_status TEXT CHECK (bridge_status IS NULL OR bridge_status IN ('PENDING', 'COMPLETED', 'FAILED', 'BRIDGE_MONITORING', 'TIMEOUT', 'REFUNDED')),
|
|
1692
|
+
bridge_status TEXT CHECK (bridge_status IS NULL OR bridge_status IN ('PENDING', 'COMPLETED', 'FAILED', 'BRIDGE_MONITORING', 'TIMEOUT', 'REFUNDED', 'PARTIALLY_FILLED', 'FILLED', 'CANCELED', 'SETTLED', 'EXPIRED')),
|
|
1663
1693
|
bridge_metadata TEXT
|
|
1664
1694
|
)`);
|
|
1665
1695
|
// Step 2: Copy existing data (bridge_status and bridge_metadata default to NULL)
|
|
@@ -1953,7 +1983,7 @@ MIGRATIONS.push({
|
|
|
1953
1983
|
error TEXT,
|
|
1954
1984
|
metadata TEXT,
|
|
1955
1985
|
network TEXT CHECK (network IS NULL OR network IN (${inList(NETWORK_TYPES)})),
|
|
1956
|
-
bridge_status TEXT CHECK (bridge_status IS NULL OR bridge_status IN ('PENDING', 'COMPLETED', 'FAILED', 'BRIDGE_MONITORING', 'TIMEOUT', 'REFUNDED')),
|
|
1986
|
+
bridge_status TEXT CHECK (bridge_status IS NULL OR bridge_status IN ('PENDING', 'COMPLETED', 'FAILED', 'BRIDGE_MONITORING', 'TIMEOUT', 'REFUNDED', 'PARTIALLY_FILLED', 'FILLED', 'CANCELED', 'SETTLED', 'EXPIRED')),
|
|
1957
1987
|
bridge_metadata TEXT
|
|
1958
1988
|
)`);
|
|
1959
1989
|
sqlite.exec(`INSERT INTO transactions_new
|
|
@@ -2688,6 +2718,161 @@ MIGRATIONS.push({
|
|
|
2688
2718
|
}
|
|
2689
2719
|
},
|
|
2690
2720
|
});
|
|
2721
|
+
// ---------------------------------------------------------------------------
|
|
2722
|
+
// v55: wallet_credentials table for External Action credential vault
|
|
2723
|
+
// ---------------------------------------------------------------------------
|
|
2724
|
+
MIGRATIONS.push({
|
|
2725
|
+
version: 55,
|
|
2726
|
+
description: 'Create wallet_credentials table for External Action credential vault',
|
|
2727
|
+
up: (sqlite) => {
|
|
2728
|
+
// Idempotent check
|
|
2729
|
+
const tables = sqlite
|
|
2730
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='wallet_credentials'")
|
|
2731
|
+
.all();
|
|
2732
|
+
if (tables.length > 0)
|
|
2733
|
+
return;
|
|
2734
|
+
sqlite.exec(`
|
|
2735
|
+
CREATE TABLE wallet_credentials (
|
|
2736
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
2737
|
+
wallet_id TEXT,
|
|
2738
|
+
type TEXT NOT NULL CHECK (type IN ('api-key','hmac-secret','rsa-private-key','session-token','custom')),
|
|
2739
|
+
name TEXT NOT NULL,
|
|
2740
|
+
encrypted_value BLOB NOT NULL,
|
|
2741
|
+
iv BLOB NOT NULL,
|
|
2742
|
+
auth_tag BLOB NOT NULL,
|
|
2743
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
2744
|
+
expires_at INTEGER,
|
|
2745
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
2746
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
2747
|
+
FOREIGN KEY (wallet_id) REFERENCES wallets(id) ON DELETE CASCADE
|
|
2748
|
+
);
|
|
2749
|
+
CREATE UNIQUE INDEX idx_wallet_credentials_wallet_name ON wallet_credentials(wallet_id, name);
|
|
2750
|
+
CREATE INDEX idx_wallet_credentials_global_name ON wallet_credentials(name) WHERE wallet_id IS NULL;
|
|
2751
|
+
CREATE INDEX idx_wallet_credentials_wallet_id ON wallet_credentials(wallet_id);
|
|
2752
|
+
CREATE INDEX idx_wallet_credentials_expires_at ON wallet_credentials(expires_at) WHERE expires_at IS NOT NULL;
|
|
2753
|
+
`);
|
|
2754
|
+
},
|
|
2755
|
+
});
|
|
2756
|
+
// ---------------------------------------------------------------------------
|
|
2757
|
+
// v56: transactions table action tracking columns
|
|
2758
|
+
// ---------------------------------------------------------------------------
|
|
2759
|
+
MIGRATIONS.push({
|
|
2760
|
+
version: 56,
|
|
2761
|
+
description: 'Add action_kind, venue, operation, external_id columns to transactions',
|
|
2762
|
+
up: (sqlite) => {
|
|
2763
|
+
// Check if columns already exist (pushSchema may have already added them)
|
|
2764
|
+
const cols = sqlite.prepare('PRAGMA table_info(transactions)').all()
|
|
2765
|
+
.map(c => c.name);
|
|
2766
|
+
if (!cols.includes('action_kind')) {
|
|
2767
|
+
sqlite.exec("ALTER TABLE transactions ADD COLUMN action_kind TEXT NOT NULL DEFAULT 'contractCall'");
|
|
2768
|
+
}
|
|
2769
|
+
if (!cols.includes('venue')) {
|
|
2770
|
+
sqlite.exec('ALTER TABLE transactions ADD COLUMN venue TEXT');
|
|
2771
|
+
}
|
|
2772
|
+
if (!cols.includes('operation')) {
|
|
2773
|
+
sqlite.exec('ALTER TABLE transactions ADD COLUMN operation TEXT');
|
|
2774
|
+
}
|
|
2775
|
+
if (!cols.includes('external_id')) {
|
|
2776
|
+
sqlite.exec('ALTER TABLE transactions ADD COLUMN external_id TEXT');
|
|
2777
|
+
}
|
|
2778
|
+
// Create indexes (idempotent with IF NOT EXISTS)
|
|
2779
|
+
sqlite.exec('CREATE INDEX IF NOT EXISTS idx_transactions_action_kind ON transactions(action_kind)');
|
|
2780
|
+
sqlite.exec('CREATE INDEX IF NOT EXISTS idx_transactions_venue ON transactions(venue) WHERE venue IS NOT NULL');
|
|
2781
|
+
sqlite.exec('CREATE INDEX IF NOT EXISTS idx_transactions_external_id ON transactions(external_id) WHERE external_id IS NOT NULL');
|
|
2782
|
+
},
|
|
2783
|
+
});
|
|
2784
|
+
// ---------------------------------------------------------------------------
|
|
2785
|
+
// v57: composite index for external action tracking queries
|
|
2786
|
+
// ---------------------------------------------------------------------------
|
|
2787
|
+
MIGRATIONS.push({
|
|
2788
|
+
version: 57,
|
|
2789
|
+
description: 'Add composite index idx_transactions_action_kind_bridge_status',
|
|
2790
|
+
up: (sqlite) => {
|
|
2791
|
+
sqlite.exec('CREATE INDEX IF NOT EXISTS idx_transactions_action_kind_bridge_status ON transactions(action_kind, bridge_status) WHERE bridge_status IS NOT NULL');
|
|
2792
|
+
},
|
|
2793
|
+
});
|
|
2794
|
+
// ---------------------------------------------------------------------------
|
|
2795
|
+
// v58: Update transactions type CHECK constraint to include CONTRACT_DEPLOY
|
|
2796
|
+
// ---------------------------------------------------------------------------
|
|
2797
|
+
MIGRATIONS.push({
|
|
2798
|
+
version: 58,
|
|
2799
|
+
description: 'Add CONTRACT_DEPLOY to transactions type CHECK constraint (12-step table recreation)',
|
|
2800
|
+
managesOwnTransaction: true,
|
|
2801
|
+
up: (sqlite) => {
|
|
2802
|
+
sqlite.exec('BEGIN');
|
|
2803
|
+
try {
|
|
2804
|
+
// Step 1: Create transactions_new with updated CHECK constraints (CONTRACT_DEPLOY in TRANSACTION_TYPES)
|
|
2805
|
+
sqlite.exec(`CREATE TABLE transactions_new (
|
|
2806
|
+
id TEXT PRIMARY KEY,
|
|
2807
|
+
wallet_id TEXT NOT NULL REFERENCES wallets(id) ON DELETE RESTRICT,
|
|
2808
|
+
session_id TEXT REFERENCES sessions(id) ON DELETE SET NULL,
|
|
2809
|
+
chain TEXT NOT NULL,
|
|
2810
|
+
tx_hash TEXT,
|
|
2811
|
+
type TEXT NOT NULL CHECK (type IN (${inList(TRANSACTION_TYPES)})),
|
|
2812
|
+
amount TEXT,
|
|
2813
|
+
to_address TEXT,
|
|
2814
|
+
token_mint TEXT,
|
|
2815
|
+
contract_address TEXT,
|
|
2816
|
+
method_signature TEXT,
|
|
2817
|
+
spender_address TEXT,
|
|
2818
|
+
approved_amount TEXT,
|
|
2819
|
+
parent_id TEXT REFERENCES transactions_new(id) ON DELETE CASCADE,
|
|
2820
|
+
batch_index INTEGER,
|
|
2821
|
+
status TEXT NOT NULL DEFAULT 'PENDING' CHECK (status IN (${inList(TRANSACTION_STATUSES)})),
|
|
2822
|
+
tier TEXT CHECK (tier IS NULL OR tier IN (${inList(POLICY_TIERS)})),
|
|
2823
|
+
queued_at INTEGER,
|
|
2824
|
+
executed_at INTEGER,
|
|
2825
|
+
created_at INTEGER NOT NULL,
|
|
2826
|
+
reserved_amount TEXT,
|
|
2827
|
+
amount_usd REAL,
|
|
2828
|
+
reserved_amount_usd REAL,
|
|
2829
|
+
error TEXT,
|
|
2830
|
+
metadata TEXT,
|
|
2831
|
+
network TEXT CHECK (network IS NULL OR network IN (${inList(NETWORK_TYPES)})),
|
|
2832
|
+
bridge_status TEXT CHECK (bridge_status IS NULL OR bridge_status IN ('PENDING', 'COMPLETED', 'FAILED', 'BRIDGE_MONITORING', 'TIMEOUT', 'REFUNDED', 'PARTIALLY_FILLED', 'FILLED', 'CANCELED', 'SETTLED', 'EXPIRED')),
|
|
2833
|
+
bridge_metadata TEXT,
|
|
2834
|
+
action_kind TEXT NOT NULL DEFAULT 'contractCall',
|
|
2835
|
+
venue TEXT,
|
|
2836
|
+
operation TEXT,
|
|
2837
|
+
external_id TEXT
|
|
2838
|
+
)`);
|
|
2839
|
+
// Step 2: Copy existing data
|
|
2840
|
+
sqlite.exec(`INSERT INTO transactions_new (id, wallet_id, session_id, chain, tx_hash, type, amount, to_address, token_mint, contract_address, method_signature, spender_address, approved_amount, parent_id, batch_index, status, tier, queued_at, executed_at, created_at, reserved_amount, amount_usd, reserved_amount_usd, error, metadata, network, bridge_status, bridge_metadata, action_kind, venue, operation, external_id)
|
|
2841
|
+
SELECT id, wallet_id, session_id, chain, tx_hash, type, amount, to_address, token_mint, contract_address, method_signature, spender_address, approved_amount, parent_id, batch_index, status, tier, queued_at, executed_at, created_at, reserved_amount, amount_usd, reserved_amount_usd, error, metadata, network, bridge_status, bridge_metadata, action_kind, venue, operation, external_id FROM transactions`);
|
|
2842
|
+
// Step 3: Drop old table
|
|
2843
|
+
sqlite.exec('DROP TABLE transactions');
|
|
2844
|
+
// Step 4: Rename new table
|
|
2845
|
+
sqlite.exec('ALTER TABLE transactions_new RENAME TO transactions');
|
|
2846
|
+
// Step 5: Recreate all 14 indexes
|
|
2847
|
+
sqlite.exec('CREATE INDEX idx_transactions_wallet_status ON transactions(wallet_id, status)');
|
|
2848
|
+
sqlite.exec('CREATE INDEX idx_transactions_session_id ON transactions(session_id)');
|
|
2849
|
+
sqlite.exec('CREATE UNIQUE INDEX idx_transactions_tx_hash ON transactions(tx_hash)');
|
|
2850
|
+
sqlite.exec('CREATE INDEX idx_transactions_queued_at ON transactions(queued_at)');
|
|
2851
|
+
sqlite.exec('CREATE INDEX idx_transactions_created_at ON transactions(created_at)');
|
|
2852
|
+
sqlite.exec('CREATE INDEX idx_transactions_type ON transactions(type)');
|
|
2853
|
+
sqlite.exec('CREATE INDEX idx_transactions_contract_address ON transactions(contract_address)');
|
|
2854
|
+
sqlite.exec('CREATE INDEX idx_transactions_parent_id ON transactions(parent_id)');
|
|
2855
|
+
sqlite.exec("CREATE INDEX idx_transactions_bridge_status ON transactions(bridge_status) WHERE bridge_status IS NOT NULL");
|
|
2856
|
+
sqlite.exec("CREATE INDEX idx_transactions_gas_waiting ON transactions(status) WHERE status = 'GAS_WAITING'");
|
|
2857
|
+
sqlite.exec('CREATE INDEX idx_transactions_action_kind ON transactions(action_kind)');
|
|
2858
|
+
sqlite.exec("CREATE INDEX idx_transactions_venue ON transactions(venue) WHERE venue IS NOT NULL");
|
|
2859
|
+
sqlite.exec("CREATE INDEX idx_transactions_external_id ON transactions(external_id) WHERE external_id IS NOT NULL");
|
|
2860
|
+
sqlite.exec('CREATE INDEX idx_transactions_action_kind_bridge_status ON transactions(action_kind, bridge_status) WHERE bridge_status IS NOT NULL');
|
|
2861
|
+
// Step 6: Commit
|
|
2862
|
+
sqlite.exec('COMMIT');
|
|
2863
|
+
}
|
|
2864
|
+
catch (err) {
|
|
2865
|
+
sqlite.exec('ROLLBACK');
|
|
2866
|
+
throw err;
|
|
2867
|
+
}
|
|
2868
|
+
// Step 7: Re-enable foreign keys and verify integrity
|
|
2869
|
+
sqlite.pragma('foreign_keys = ON');
|
|
2870
|
+
const fkErrors = sqlite.pragma('foreign_key_check');
|
|
2871
|
+
if (fkErrors.length > 0) {
|
|
2872
|
+
throw new Error(`FK integrity violation after v58: ${JSON.stringify(fkErrors)}`);
|
|
2873
|
+
}
|
|
2874
|
+
},
|
|
2875
|
+
});
|
|
2691
2876
|
/**
|
|
2692
2877
|
* Run incremental migrations against the database.
|
|
2693
2878
|
*
|