@magicblock-console/core 0.1.0
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/client.d.ts +98 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +96 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +94 -0
- package/dist/config.js.map +1 -0
- package/dist/connection.d.ts +42 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +82 -0
- package/dist/connection.js.map +1 -0
- package/dist/cranks.d.ts +14 -0
- package/dist/cranks.d.ts.map +1 -0
- package/dist/cranks.js +128 -0
- package/dist/cranks.js.map +1 -0
- package/dist/er.d.ts +17 -0
- package/dist/er.d.ts.map +1 -0
- package/dist/er.js +314 -0
- package/dist/er.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/monitor.d.ts +21 -0
- package/dist/monitor.d.ts.map +1 -0
- package/dist/monitor.js +170 -0
- package/dist/monitor.js.map +1 -0
- package/dist/oracle.d.ts +13 -0
- package/dist/oracle.d.ts.map +1 -0
- package/dist/oracle.js +215 -0
- package/dist/oracle.js.map +1 -0
- package/dist/privacy.d.ts +14 -0
- package/dist/privacy.d.ts.map +1 -0
- package/dist/privacy.js +177 -0
- package/dist/privacy.js.map +1 -0
- package/dist/projects.d.ts +9 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +94 -0
- package/dist/projects.js.map +1 -0
- package/dist/storage.d.ts +37 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +150 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +180 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +18 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +43 -0
- package/dist/utils.js.map +1 -0
- package/dist/vrf.d.ts +42 -0
- package/dist/vrf.d.ts.map +1 -0
- package/dist/vrf.js +117 -0
- package/dist/vrf.js.map +1 -0
- package/package.json +30 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { ClientOptions, CommitOptions, CommitResult, ConfigureProjectOptions, CostBreakdown, Crank, CrankCreateOptions, CreateProjectOptions, DelegateOptions, DelegatedAccount, DelegationResult, DelegationStatus, LogEntry, Network, PriceFeed, PriceFeedOptions, PrivacyDepositOptions, PrivacyResult, PrivacyTransferOptions, PrivacyWithdrawOptions, Project, ProjectStatus, StateDiff, UndelegateOptions, VrfRequestOptions, VrfResult } from './types.js';
|
|
2
|
+
import { type Storage } from './storage.js';
|
|
3
|
+
import type { SolanaSignerAdapter } from './connection.js';
|
|
4
|
+
export interface ProjectsNamespace {
|
|
5
|
+
create(options: CreateProjectOptions): Promise<Project>;
|
|
6
|
+
get(name: string): Promise<Project>;
|
|
7
|
+
list(): Promise<Project[]>;
|
|
8
|
+
configure(name: string, options: ConfigureProjectOptions): Promise<Project>;
|
|
9
|
+
delete(name: string): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export interface ErNamespace {
|
|
12
|
+
delegate(options: DelegateOptions): Promise<DelegationResult>;
|
|
13
|
+
undelegate(options: UndelegateOptions): Promise<DelegationResult>;
|
|
14
|
+
commit(options: CommitOptions): Promise<CommitResult>;
|
|
15
|
+
status(account: string): Promise<DelegationStatus>;
|
|
16
|
+
accounts(project: string): Promise<DelegatedAccount[]>;
|
|
17
|
+
diff(account: string): Promise<StateDiff>;
|
|
18
|
+
}
|
|
19
|
+
export interface VrfNamespace {
|
|
20
|
+
request(options: VrfRequestOptions): Promise<VrfResult>;
|
|
21
|
+
}
|
|
22
|
+
export interface PrivacyNamespace {
|
|
23
|
+
deposit(options: PrivacyDepositOptions): Promise<PrivacyResult>;
|
|
24
|
+
transfer(options: PrivacyTransferOptions): Promise<PrivacyResult>;
|
|
25
|
+
withdraw(options: PrivacyWithdrawOptions): Promise<PrivacyResult>;
|
|
26
|
+
}
|
|
27
|
+
export interface CranksNamespace {
|
|
28
|
+
create(options: CrankCreateOptions): Promise<Crank>;
|
|
29
|
+
list(project: string): Promise<Crank[]>;
|
|
30
|
+
stop(crankId: string): Promise<Crank>;
|
|
31
|
+
}
|
|
32
|
+
export interface OracleNamespace {
|
|
33
|
+
getPrice(options: PriceFeedOptions): Promise<PriceFeed>;
|
|
34
|
+
}
|
|
35
|
+
export interface MonitorNamespace {
|
|
36
|
+
status(project: string): Promise<ProjectStatus>;
|
|
37
|
+
costs(project: string, period?: string): Promise<CostBreakdown>;
|
|
38
|
+
logs(project: string, limit?: number): Promise<LogEntry[]>;
|
|
39
|
+
}
|
|
40
|
+
export interface NamespaceOverrides {
|
|
41
|
+
projects?: ProjectsNamespace;
|
|
42
|
+
er?: ErNamespace;
|
|
43
|
+
vrf?: VrfNamespace;
|
|
44
|
+
privacy?: PrivacyNamespace;
|
|
45
|
+
cranks?: CranksNamespace;
|
|
46
|
+
oracle?: OracleNamespace;
|
|
47
|
+
monitor?: MonitorNamespace;
|
|
48
|
+
}
|
|
49
|
+
export declare class ConsoleClient {
|
|
50
|
+
readonly network: Network;
|
|
51
|
+
readonly storage: Storage;
|
|
52
|
+
readonly projects: ProjectsNamespace;
|
|
53
|
+
readonly er: ErNamespace;
|
|
54
|
+
readonly vrf: VrfNamespace;
|
|
55
|
+
readonly privacy: PrivacyNamespace;
|
|
56
|
+
readonly cranks: CranksNamespace;
|
|
57
|
+
readonly oracle: OracleNamespace;
|
|
58
|
+
readonly monitor: MonitorNamespace;
|
|
59
|
+
private _connection?;
|
|
60
|
+
constructor(options?: ClientOptions, namespaces?: NamespaceOverrides);
|
|
61
|
+
/**
|
|
62
|
+
* Connect to Solana using a local keypair file.
|
|
63
|
+
* Enables real on-chain transactions for ER operations.
|
|
64
|
+
* Typically used by CLI and MCP server.
|
|
65
|
+
*
|
|
66
|
+
* Connection module is loaded dynamically to avoid pulling Node.js-only
|
|
67
|
+
* dependencies (@solana/web3.js, MagicBlock SDK) into browser bundles.
|
|
68
|
+
*/
|
|
69
|
+
connectWithKeypair(keypairPath: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Connect in read-only mode (no signer).
|
|
72
|
+
* Enables querying real on-chain data (status, diff) without
|
|
73
|
+
* the ability to send transactions.
|
|
74
|
+
*
|
|
75
|
+
* Note: requires Node.js environment (uses @solana/web3.js Connection).
|
|
76
|
+
*/
|
|
77
|
+
connectReadOnly(): Promise<void>;
|
|
78
|
+
/** Returns true if a blockchain connection is active. */
|
|
79
|
+
get isConnected(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Connect using a browser wallet adapter (e.g. Phantom).
|
|
82
|
+
* The signer must provide `publicKey` and `signTransaction`.
|
|
83
|
+
*
|
|
84
|
+
* Connection module is loaded dynamically to avoid pulling Node.js-only
|
|
85
|
+
* dependencies into browser bundles.
|
|
86
|
+
*/
|
|
87
|
+
connectWithSigner(signer: SolanaSignerAdapter): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Disconnect from the blockchain.
|
|
90
|
+
* Namespaces automatically fall back to simulated mode.
|
|
91
|
+
*/
|
|
92
|
+
disconnect(): void;
|
|
93
|
+
/** Returns true if the connection has a signer (can send transactions). */
|
|
94
|
+
get canSign(): boolean;
|
|
95
|
+
}
|
|
96
|
+
/** Create a new ConsoleClient instance. */
|
|
97
|
+
export declare function createClient(options?: ClientOptions, namespaces?: NamespaceOverrides): ConsoleClient;
|
|
98
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { MemoryStorage } from './storage.js';
|
|
2
|
+
import { createProjectsNamespace } from './projects.js';
|
|
3
|
+
import { createErNamespace } from './er.js';
|
|
4
|
+
import { createVrfNamespace } from './vrf.js';
|
|
5
|
+
import { createPrivacyNamespace } from './privacy.js';
|
|
6
|
+
import { createCranksNamespace } from './cranks.js';
|
|
7
|
+
import { createOracleNamespace } from './oracle.js';
|
|
8
|
+
import { createMonitorNamespace } from './monitor.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ConsoleClient
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
export class ConsoleClient {
|
|
13
|
+
network;
|
|
14
|
+
storage;
|
|
15
|
+
projects;
|
|
16
|
+
er;
|
|
17
|
+
vrf;
|
|
18
|
+
privacy;
|
|
19
|
+
cranks;
|
|
20
|
+
oracle;
|
|
21
|
+
monitor;
|
|
22
|
+
_connection;
|
|
23
|
+
constructor(options = {}, namespaces = {}) {
|
|
24
|
+
this.network = options.network ?? 'devnet';
|
|
25
|
+
this.storage = options.storage ?? new MemoryStorage();
|
|
26
|
+
// Wire real implementations with stub fallbacks
|
|
27
|
+
this.projects = namespaces.projects ?? createProjectsNamespace(this.storage);
|
|
28
|
+
this.er = namespaces.er ?? createErNamespace(this.storage, this.network, async (project) => {
|
|
29
|
+
const p = await this.projects.get(project);
|
|
30
|
+
return p.region;
|
|
31
|
+
}, () => this._connection);
|
|
32
|
+
this.vrf = namespaces.vrf ?? createVrfNamespace(this.storage, this.network);
|
|
33
|
+
this.privacy = namespaces.privacy ?? createPrivacyNamespace(this.storage, this.network, () => this._connection);
|
|
34
|
+
this.cranks = namespaces.cranks ?? createCranksNamespace(this.storage, this.network, () => this._connection);
|
|
35
|
+
this.oracle = namespaces.oracle ?? createOracleNamespace(this.storage, this.network, () => this._connection);
|
|
36
|
+
this.monitor = namespaces.monitor ?? createMonitorNamespace(this.storage, this.network);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Connect to Solana using a local keypair file.
|
|
40
|
+
* Enables real on-chain transactions for ER operations.
|
|
41
|
+
* Typically used by CLI and MCP server.
|
|
42
|
+
*
|
|
43
|
+
* Connection module is loaded dynamically to avoid pulling Node.js-only
|
|
44
|
+
* dependencies (@solana/web3.js, MagicBlock SDK) into browser bundles.
|
|
45
|
+
*/
|
|
46
|
+
async connectWithKeypair(keypairPath) {
|
|
47
|
+
const { createKeypairSigner, createBlockchainConnection } = await import('./connection.js');
|
|
48
|
+
const signer = await createKeypairSigner(keypairPath);
|
|
49
|
+
this._connection = createBlockchainConnection(this.network, signer);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Connect in read-only mode (no signer).
|
|
53
|
+
* Enables querying real on-chain data (status, diff) without
|
|
54
|
+
* the ability to send transactions.
|
|
55
|
+
*
|
|
56
|
+
* Note: requires Node.js environment (uses @solana/web3.js Connection).
|
|
57
|
+
*/
|
|
58
|
+
async connectReadOnly() {
|
|
59
|
+
const { createReadOnlyConnection } = await import('./connection.js');
|
|
60
|
+
this._connection = createReadOnlyConnection(this.network);
|
|
61
|
+
}
|
|
62
|
+
/** Returns true if a blockchain connection is active. */
|
|
63
|
+
get isConnected() {
|
|
64
|
+
return this._connection !== undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Connect using a browser wallet adapter (e.g. Phantom).
|
|
68
|
+
* The signer must provide `publicKey` and `signTransaction`.
|
|
69
|
+
*
|
|
70
|
+
* Connection module is loaded dynamically to avoid pulling Node.js-only
|
|
71
|
+
* dependencies into browser bundles.
|
|
72
|
+
*/
|
|
73
|
+
async connectWithSigner(signer) {
|
|
74
|
+
const { createBlockchainConnection } = await import('./connection.js');
|
|
75
|
+
this._connection = createBlockchainConnection(this.network, signer);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Disconnect from the blockchain.
|
|
79
|
+
* Namespaces automatically fall back to simulated mode.
|
|
80
|
+
*/
|
|
81
|
+
disconnect() {
|
|
82
|
+
this._connection = undefined;
|
|
83
|
+
}
|
|
84
|
+
/** Returns true if the connection has a signer (can send transactions). */
|
|
85
|
+
get canSign() {
|
|
86
|
+
return this._connection?.signer !== undefined;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// Factory
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
/** Create a new ConsoleClient instance. */
|
|
93
|
+
export function createClient(options = {}, namespaces = {}) {
|
|
94
|
+
return new ConsoleClient(options, namespaces);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { FeatureFlags, Network, Region } from './types.js';
|
|
2
|
+
export interface RegionEndpoints {
|
|
3
|
+
http: string;
|
|
4
|
+
ws: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RegionConfig {
|
|
7
|
+
devnet: RegionEndpoints;
|
|
8
|
+
mainnet: RegionEndpoints;
|
|
9
|
+
}
|
|
10
|
+
export declare const REGIONS: Record<Region, RegionConfig>;
|
|
11
|
+
export declare const PROGRAM_IDS: {
|
|
12
|
+
readonly delegation: "DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh";
|
|
13
|
+
readonly magic: "Magic11111111111111111111111111111111111111";
|
|
14
|
+
readonly magicContext: "MagicContext1111111111111111111111111111111";
|
|
15
|
+
readonly permission: "ACLseoPoyC3cBqoUtkbjZ4aDrkurZW86v19pXz2XQnp1";
|
|
16
|
+
readonly ephemeralSplToken: "SPLxh1LVZzEkX99H6rqYizhytLWPZVV296zyYDPagv2";
|
|
17
|
+
readonly pythReceiver: "rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ";
|
|
18
|
+
};
|
|
19
|
+
export interface ValidatorSet {
|
|
20
|
+
us: string;
|
|
21
|
+
eu: string;
|
|
22
|
+
asia: string;
|
|
23
|
+
tee: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* ER validator pubkeys per network and region.
|
|
27
|
+
* NOTE: Mainnet keys currently mirror devnet — MagicBlock has not yet
|
|
28
|
+
* published separate mainnet validator identities.
|
|
29
|
+
*/
|
|
30
|
+
export declare const VALIDATORS: Record<Network, ValidatorSet>;
|
|
31
|
+
export interface RouterEndpoints {
|
|
32
|
+
http: string;
|
|
33
|
+
ws: string;
|
|
34
|
+
}
|
|
35
|
+
export declare const MAGIC_ROUTER: Record<Network, RouterEndpoints>;
|
|
36
|
+
export declare const DEFAULT_FEATURES: FeatureFlags;
|
|
37
|
+
/** Resolve region-specific endpoints for a given network. */
|
|
38
|
+
export declare function getRegionConfig(region: Region, network: Network): RegionEndpoints;
|
|
39
|
+
/** Resolve Magic Router endpoints for a given network. */
|
|
40
|
+
export declare function getMagicRouterEndpoints(network: Network): RouterEndpoints;
|
|
41
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAMhE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA+BhD,CAAC;AAMF,eAAO,MAAM,WAAW;;;;;;;CAOd,CAAC;AAMX,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,OAAO,EAAE,YAAY,CAapD,CAAC;AAMF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,eAAe,CASzD,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,YAM9B,CAAC;AAMF,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe,CAEjF;AAED,0DAA0D;AAC1D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAEzE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export const REGIONS = {
|
|
2
|
+
us: {
|
|
3
|
+
devnet: {
|
|
4
|
+
http: 'https://devnet-us.magicblock.app',
|
|
5
|
+
ws: 'wss://devnet-us.magicblock.app',
|
|
6
|
+
},
|
|
7
|
+
mainnet: {
|
|
8
|
+
http: 'https://us.magicblock.app',
|
|
9
|
+
ws: 'wss://us.magicblock.app',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
eu: {
|
|
13
|
+
devnet: {
|
|
14
|
+
http: 'https://devnet-eu.magicblock.app',
|
|
15
|
+
ws: 'wss://devnet-eu.magicblock.app',
|
|
16
|
+
},
|
|
17
|
+
mainnet: {
|
|
18
|
+
http: 'https://eu.magicblock.app',
|
|
19
|
+
ws: 'wss://eu.magicblock.app',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
asia: {
|
|
23
|
+
devnet: {
|
|
24
|
+
http: 'https://devnet-as.magicblock.app',
|
|
25
|
+
ws: 'wss://devnet-as.magicblock.app',
|
|
26
|
+
},
|
|
27
|
+
mainnet: {
|
|
28
|
+
http: 'https://as.magicblock.app',
|
|
29
|
+
ws: 'wss://as.magicblock.app',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Program IDs
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
export const PROGRAM_IDS = {
|
|
37
|
+
delegation: 'DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh',
|
|
38
|
+
magic: 'Magic11111111111111111111111111111111111111',
|
|
39
|
+
magicContext: 'MagicContext1111111111111111111111111111111',
|
|
40
|
+
permission: 'ACLseoPoyC3cBqoUtkbjZ4aDrkurZW86v19pXz2XQnp1',
|
|
41
|
+
ephemeralSplToken: 'SPLxh1LVZzEkX99H6rqYizhytLWPZVV296zyYDPagv2',
|
|
42
|
+
pythReceiver: 'rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ',
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* ER validator pubkeys per network and region.
|
|
46
|
+
* NOTE: Mainnet keys currently mirror devnet — MagicBlock has not yet
|
|
47
|
+
* published separate mainnet validator identities.
|
|
48
|
+
*/
|
|
49
|
+
export const VALIDATORS = {
|
|
50
|
+
devnet: {
|
|
51
|
+
us: 'MUS3hc9TCw4cGC12vHNoYcCGzJG1txjgQLZWVoeNHNd',
|
|
52
|
+
eu: 'MEUGGrYPxKk17hCr7wpT6s8dtNokZj5U2L57vjYMS8e',
|
|
53
|
+
asia: 'MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57',
|
|
54
|
+
tee: 'MTEWGuqxUpYZGFJQcp8tLN7x5v9BSeoFHYWQQ3n3xzo',
|
|
55
|
+
},
|
|
56
|
+
mainnet: {
|
|
57
|
+
us: 'MUS3hc9TCw4cGC12vHNoYcCGzJG1txjgQLZWVoeNHNd',
|
|
58
|
+
eu: 'MEUGGrYPxKk17hCr7wpT6s8dtNokZj5U2L57vjYMS8e',
|
|
59
|
+
asia: 'MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57',
|
|
60
|
+
tee: 'MTEWGuqxUpYZGFJQcp8tLN7x5v9BSeoFHYWQQ3n3xzo',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
export const MAGIC_ROUTER = {
|
|
64
|
+
devnet: {
|
|
65
|
+
http: 'https://devnet-router.magicblock.app',
|
|
66
|
+
ws: 'wss://devnet-router.magicblock.app',
|
|
67
|
+
},
|
|
68
|
+
mainnet: {
|
|
69
|
+
http: 'https://router.magicblock.app',
|
|
70
|
+
ws: 'wss://router.magicblock.app',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Defaults
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
export const DEFAULT_FEATURES = {
|
|
77
|
+
gasless: false,
|
|
78
|
+
privacy: false,
|
|
79
|
+
vrf: false,
|
|
80
|
+
cranks: false,
|
|
81
|
+
oracle: false,
|
|
82
|
+
};
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Helpers
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
/** Resolve region-specific endpoints for a given network. */
|
|
87
|
+
export function getRegionConfig(region, network) {
|
|
88
|
+
return REGIONS[region][network];
|
|
89
|
+
}
|
|
90
|
+
/** Resolve Magic Router endpoints for a given network. */
|
|
91
|
+
export function getMagicRouterEndpoints(network) {
|
|
92
|
+
return MAGIC_ROUTER[network];
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,MAAM,OAAO,GAAiC;IACnD,EAAE,EAAE;QACF,MAAM,EAAE;YACN,IAAI,EAAE,kCAAkC;YACxC,EAAE,EAAE,gCAAgC;SACrC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,2BAA2B;YACjC,EAAE,EAAE,yBAAyB;SAC9B;KACF;IACD,EAAE,EAAE;QACF,MAAM,EAAE;YACN,IAAI,EAAE,kCAAkC;YACxC,EAAE,EAAE,gCAAgC;SACrC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,2BAA2B;YACjC,EAAE,EAAE,yBAAyB;SAC9B;KACF;IACD,IAAI,EAAE;QACJ,MAAM,EAAE;YACN,IAAI,EAAE,kCAAkC;YACxC,EAAE,EAAE,gCAAgC;SACrC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,2BAA2B;YACjC,EAAE,EAAE,yBAAyB;SAC9B;KACF;CACF,CAAC;AAEF,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,UAAU,EAAE,8CAA8C;IAC1D,KAAK,EAAE,6CAA6C;IACpD,YAAY,EAAE,6CAA6C;IAC3D,UAAU,EAAE,8CAA8C;IAC1D,iBAAiB,EAAE,6CAA6C;IAChE,YAAY,EAAE,6CAA6C;CACnD,CAAC;AAaX;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAkC;IACvD,MAAM,EAAE;QACN,EAAE,EAAE,6CAA6C;QACjD,EAAE,EAAE,6CAA6C;QACjD,IAAI,EAAE,6CAA6C;QACnD,GAAG,EAAE,6CAA6C;KACnD;IACD,OAAO,EAAE;QACP,EAAE,EAAE,6CAA6C;QACjD,EAAE,EAAE,6CAA6C;QACjD,IAAI,EAAE,6CAA6C;QACnD,GAAG,EAAE,6CAA6C;KACnD;CACF,CAAC;AAWF,MAAM,CAAC,MAAM,YAAY,GAAqC;IAC5D,MAAM,EAAE;QACN,IAAI,EAAE,sCAAsC;QAC5C,EAAE,EAAE,oCAAoC;KACzC;IACD,OAAO,EAAE;QACP,IAAI,EAAE,+BAA+B;QACrC,EAAE,EAAE,6BAA6B;KAClC;CACF,CAAC;AAEF,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;IACd,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,6DAA6D;AAC7D,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,OAAgB;IAC9D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Connection, PublicKey, Transaction } from '@solana/web3.js';
|
|
2
|
+
import { ConnectionMagicRouter } from '@magicblock-labs/ephemeral-rollups-sdk';
|
|
3
|
+
import type { Network } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Adapter bridging a Solana Keypair (or wallet adapter) into a uniform
|
|
6
|
+
* signing interface used by the Console SDK.
|
|
7
|
+
*/
|
|
8
|
+
export interface SolanaSignerAdapter {
|
|
9
|
+
publicKey: PublicKey;
|
|
10
|
+
signTransaction(tx: Transaction): Promise<Transaction>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Holds all the connections needed to interact with the Solana base layer,
|
|
14
|
+
* the Magic Router, and regional ER validators.
|
|
15
|
+
*/
|
|
16
|
+
export interface BlockchainConnection {
|
|
17
|
+
/** Standard Solana RPC connection (devnet / mainnet). */
|
|
18
|
+
baseConnection: Connection;
|
|
19
|
+
/** Magic Router connection for delegation routing. */
|
|
20
|
+
routerConnection: ConnectionMagicRouter;
|
|
21
|
+
/** Regional ER endpoint connections keyed by region id. */
|
|
22
|
+
erConnections: Record<string, Connection>;
|
|
23
|
+
/** Signer for building and sending transactions (undefined = read-only). */
|
|
24
|
+
signer?: SolanaSignerAdapter;
|
|
25
|
+
/** Active network. */
|
|
26
|
+
network: Network;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a `SolanaSignerAdapter` from a local keypair JSON file.
|
|
30
|
+
* The file should contain a JSON array of 64 bytes (Solana CLI format).
|
|
31
|
+
*/
|
|
32
|
+
export declare function createKeypairSigner(keypairPath: string): Promise<SolanaSignerAdapter>;
|
|
33
|
+
/**
|
|
34
|
+
* Create a full `BlockchainConnection` with signer for sending transactions.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createBlockchainConnection(network: Network, signer: SolanaSignerAdapter): BlockchainConnection;
|
|
37
|
+
/**
|
|
38
|
+
* Create a read-only `BlockchainConnection` (no signer).
|
|
39
|
+
* Useful for querying delegation status and account data without signing.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createReadOnlyConnection(network: Network): BlockchainConnection;
|
|
42
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,SAAS,EACT,WAAW,EACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAO1C;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACxD;AAMD;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,cAAc,EAAE,UAAU,CAAC;IAC3B,sDAAsD;IACtD,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC1C,4EAA4E;IAC5E,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,sBAAsB;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAqC9B;AAWD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,mBAAmB,GAC1B,oBAAoB,CAEtB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,GACf,oBAAoB,CAEtB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Connection, Keypair, } from '@solana/web3.js';
|
|
2
|
+
import { ConnectionMagicRouter } from '@magicblock-labs/ephemeral-rollups-sdk';
|
|
3
|
+
import { MAGIC_ROUTER, REGIONS } from './config.js';
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Keypair Signer
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* Create a `SolanaSignerAdapter` from a local keypair JSON file.
|
|
9
|
+
* The file should contain a JSON array of 64 bytes (Solana CLI format).
|
|
10
|
+
*/
|
|
11
|
+
export async function createKeypairSigner(keypairPath) {
|
|
12
|
+
const fs = await import('node:fs/promises');
|
|
13
|
+
const path = await import('node:path');
|
|
14
|
+
const resolved = path.resolve(keypairPath);
|
|
15
|
+
if (!resolved.endsWith('.json')) {
|
|
16
|
+
throw new Error('Keypair file must be a .json file');
|
|
17
|
+
}
|
|
18
|
+
const raw = await fs.readFile(resolved, 'utf-8');
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(raw);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
throw new Error('Invalid keypair file: must contain valid JSON');
|
|
25
|
+
}
|
|
26
|
+
if (!Array.isArray(parsed) ||
|
|
27
|
+
parsed.length !== 64 ||
|
|
28
|
+
!parsed.every((n) => typeof n === 'number' && n >= 0 && n <= 255)) {
|
|
29
|
+
throw new Error('Invalid keypair file: must contain a JSON array of 64 bytes');
|
|
30
|
+
}
|
|
31
|
+
const secretKey = Uint8Array.from(parsed);
|
|
32
|
+
const keypair = Keypair.fromSecretKey(secretKey);
|
|
33
|
+
// Zero out intermediate buffer
|
|
34
|
+
secretKey.fill(0);
|
|
35
|
+
return {
|
|
36
|
+
publicKey: keypair.publicKey,
|
|
37
|
+
async signTransaction(tx) {
|
|
38
|
+
tx.partialSign(keypair);
|
|
39
|
+
return tx;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Connection Factories
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
const SOLANA_RPC = {
|
|
47
|
+
devnet: 'https://api.devnet.solana.com',
|
|
48
|
+
mainnet: 'https://api.mainnet-beta.solana.com',
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Create a full `BlockchainConnection` with signer for sending transactions.
|
|
52
|
+
*/
|
|
53
|
+
export function createBlockchainConnection(network, signer) {
|
|
54
|
+
return buildConnection(network, signer);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a read-only `BlockchainConnection` (no signer).
|
|
58
|
+
* Useful for querying delegation status and account data without signing.
|
|
59
|
+
*/
|
|
60
|
+
export function createReadOnlyConnection(network) {
|
|
61
|
+
return buildConnection(network);
|
|
62
|
+
}
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Internal
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
function buildConnection(network, signer) {
|
|
67
|
+
const baseConnection = new Connection(SOLANA_RPC[network], 'confirmed');
|
|
68
|
+
const routerUrl = MAGIC_ROUTER[network].http;
|
|
69
|
+
const routerConnection = new ConnectionMagicRouter(routerUrl, 'confirmed');
|
|
70
|
+
const erConnections = {};
|
|
71
|
+
for (const [region, config] of Object.entries(REGIONS)) {
|
|
72
|
+
erConnections[region] = new Connection(config[network].http, 'confirmed');
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
baseConnection,
|
|
76
|
+
routerConnection,
|
|
77
|
+
erConnections,
|
|
78
|
+
signer,
|
|
79
|
+
network,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/cranks.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Storage } from './storage.js';
|
|
2
|
+
import type { Network } from './types.js';
|
|
3
|
+
import type { CranksNamespace } from './client.js';
|
|
4
|
+
import type { BlockchainConnection } from './connection.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create a fully-functional `CranksNamespace` backed by the given Storage.
|
|
7
|
+
*
|
|
8
|
+
* When a `getConnection` callback returns a valid `BlockchainConnection`
|
|
9
|
+
* with a signer, and the `account` option is provided, a real
|
|
10
|
+
* `createCommitInstruction` is sent to the ER validator.
|
|
11
|
+
* Otherwise, crank creation falls back to simulated behavior.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createCranksNamespace(storage: Storage, _network: Network, getConnection?: () => BlockchainConnection | undefined): CranksNamespace;
|
|
14
|
+
//# sourceMappingURL=cranks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cranks.d.ts","sourceRoot":"","sources":["../src/cranks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,OAAO,EAIR,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA4C5D;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,MAAM,oBAAoB,GAAG,SAAS,GACrD,eAAe,CAwHjB"}
|
package/dist/cranks.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { generateBase58 } from './utils.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Key helpers
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
const CRANK_PREFIX = 'crank:';
|
|
6
|
+
const CRANK_INDEX_PREFIX = 'crank-index:';
|
|
7
|
+
function crankKey(id) {
|
|
8
|
+
return `${CRANK_PREFIX}${id}`;
|
|
9
|
+
}
|
|
10
|
+
function crankIndexKey(project) {
|
|
11
|
+
return `${CRANK_INDEX_PREFIX}${project}`;
|
|
12
|
+
}
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Helpers
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Load a project from storage and validate that the cranks feature is enabled.
|
|
18
|
+
*/
|
|
19
|
+
async function requireCranksEnabled(storage, project) {
|
|
20
|
+
const data = await storage.get(`project:${project}`);
|
|
21
|
+
if (!data) {
|
|
22
|
+
throw new Error(`Project "${project}" not found`);
|
|
23
|
+
}
|
|
24
|
+
const parsed = JSON.parse(data);
|
|
25
|
+
if (!parsed.features.cranks) {
|
|
26
|
+
throw new Error(`Feature "cranks" is not enabled for project "${project}". ` +
|
|
27
|
+
`Enable it with: client.projects.configure("${project}", { features: { cranks: true } })`);
|
|
28
|
+
}
|
|
29
|
+
return parsed;
|
|
30
|
+
}
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Factory
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* Create a fully-functional `CranksNamespace` backed by the given Storage.
|
|
36
|
+
*
|
|
37
|
+
* When a `getConnection` callback returns a valid `BlockchainConnection`
|
|
38
|
+
* with a signer, and the `account` option is provided, a real
|
|
39
|
+
* `createCommitInstruction` is sent to the ER validator.
|
|
40
|
+
* Otherwise, crank creation falls back to simulated behavior.
|
|
41
|
+
*/
|
|
42
|
+
export function createCranksNamespace(storage, _network, getConnection) {
|
|
43
|
+
// Helper: read the crank index for a project
|
|
44
|
+
async function getCrankIndex(project) {
|
|
45
|
+
const data = await storage.get(crankIndexKey(project));
|
|
46
|
+
return data ? JSON.parse(data) : [];
|
|
47
|
+
}
|
|
48
|
+
// Helper: write the crank index for a project
|
|
49
|
+
async function setCrankIndex(project, ids) {
|
|
50
|
+
await storage.set(crankIndexKey(project), JSON.stringify(ids));
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
async create(options) {
|
|
54
|
+
await requireCranksEnabled(storage, options.project);
|
|
55
|
+
if (options.intervalMs <= 0) {
|
|
56
|
+
throw new Error('intervalMs must be greater than 0');
|
|
57
|
+
}
|
|
58
|
+
const id = `crank_${Date.now().toString(36)}_${generateBase58(6)}`;
|
|
59
|
+
let commitSignature;
|
|
60
|
+
let simulated = true;
|
|
61
|
+
// Real blockchain: send initial commit instruction
|
|
62
|
+
const conn = getConnection?.();
|
|
63
|
+
if (options.account && conn?.signer) {
|
|
64
|
+
try {
|
|
65
|
+
const { PublicKey, Transaction } = await import('@solana/web3.js');
|
|
66
|
+
const { createCommitInstruction } = await import('@magicblock-labs/ephemeral-rollups-sdk');
|
|
67
|
+
const accountPk = new PublicKey(options.account);
|
|
68
|
+
const ix = createCommitInstruction(conn.signer.publicKey, [accountPk]);
|
|
69
|
+
const tx = new Transaction().add(ix);
|
|
70
|
+
tx.feePayer = conn.signer.publicKey;
|
|
71
|
+
// Commit is a base chain operation
|
|
72
|
+
tx.recentBlockhash = (await conn.baseConnection.getLatestBlockhash()).blockhash;
|
|
73
|
+
const signed = await conn.signer.signTransaction(tx);
|
|
74
|
+
commitSignature = await conn.baseConnection.sendRawTransaction(signed.serialize());
|
|
75
|
+
simulated = false;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
console.debug(`[mb-console] Real crank commit failed, using simulated mode: ${err instanceof Error ? err.message : String(err)}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const crank = {
|
|
82
|
+
id,
|
|
83
|
+
intervalMs: options.intervalMs,
|
|
84
|
+
iterations: options.iterations ?? 0,
|
|
85
|
+
executed: 0,
|
|
86
|
+
status: 'running',
|
|
87
|
+
account: options.account,
|
|
88
|
+
commitSignature,
|
|
89
|
+
simulated,
|
|
90
|
+
};
|
|
91
|
+
// Persist crank record
|
|
92
|
+
await storage.set(crankKey(id), JSON.stringify(crank));
|
|
93
|
+
// Update project crank index
|
|
94
|
+
const index = await getCrankIndex(options.project);
|
|
95
|
+
index.push(id);
|
|
96
|
+
await setCrankIndex(options.project, index);
|
|
97
|
+
return crank;
|
|
98
|
+
},
|
|
99
|
+
async list(project) {
|
|
100
|
+
const index = await getCrankIndex(project);
|
|
101
|
+
const cranks = [];
|
|
102
|
+
for (const id of index) {
|
|
103
|
+
const data = await storage.get(crankKey(id));
|
|
104
|
+
if (data) {
|
|
105
|
+
cranks.push(JSON.parse(data));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return cranks;
|
|
109
|
+
},
|
|
110
|
+
async stop(crankId) {
|
|
111
|
+
const data = await storage.get(crankKey(crankId));
|
|
112
|
+
if (!data) {
|
|
113
|
+
throw new Error(`Crank "${crankId}" not found`);
|
|
114
|
+
}
|
|
115
|
+
const crank = JSON.parse(data);
|
|
116
|
+
if (crank.status === 'stopped') {
|
|
117
|
+
throw new Error(`Crank "${crankId}" is already stopped`);
|
|
118
|
+
}
|
|
119
|
+
if (crank.status === 'completed') {
|
|
120
|
+
throw new Error(`Crank "${crankId}" has already completed`);
|
|
121
|
+
}
|
|
122
|
+
crank.status = 'stopped';
|
|
123
|
+
await storage.set(crankKey(crankId), JSON.stringify(crank));
|
|
124
|
+
return crank;
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=cranks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cranks.js","sourceRoot":"","sources":["../src/cranks.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,YAAY,GAAG,QAAQ,CAAC;AAC9B,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAE1C,SAAS,QAAQ,CAAC,EAAU;IAC1B,OAAO,GAAG,YAAY,GAAG,EAAE,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,GAAG,kBAAkB,GAAG,OAAO,EAAE,CAAC;AAC3C,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;GAEG;AACH,KAAK,UAAU,oBAAoB,CAAC,OAAgB,EAAE,OAAe;IACnE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;IACrD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,aAAa,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,gDAAgD,OAAO,KAAK;YAC1D,8CAA8C,OAAO,oCAAoC,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAgB,EAChB,QAAiB,EACjB,aAAsD;IAEtD,6CAA6C;IAC7C,KAAK,UAAU,aAAa,CAAC,OAAe;QAC1C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,CAAC;IAED,8CAA8C;IAC9C,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,GAAa;QACzD,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,OAA2B;YACtC,MAAM,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAErD,IAAI,OAAO,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;YAED,MAAM,EAAE,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,IAAI,eAAmC,CAAC;YACxC,IAAI,SAAS,GAAG,IAAI,CAAC;YAErB,mDAAmD;YACnD,MAAM,IAAI,GAAG,aAAa,EAAE,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACH,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;oBACnE,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAC9C,wCAAwC,CACzC,CAAC;oBAEF,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBAEjD,MAAM,EAAE,GAAG,uBAAuB,CAChC,IAAI,CAAC,MAAM,CAAC,SAAS,EACrB,CAAC,SAAS,CAAC,CACZ,CAAC;oBAEF,MAAM,EAAE,GAAG,IAAI,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACrC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;oBAEpC,mCAAmC;oBACnC,EAAE,CAAC,eAAe,GAAG,CACnB,MAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,EAAE,CAC/C,CAAC,SAAS,CAAC;oBAEZ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;oBACrD,eAAe,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAC5D,MAAM,CAAC,SAAS,EAAE,CACnB,CAAC;oBACF,SAAS,GAAG,KAAK,CAAC;gBACpB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CACX,gEACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAU;gBACnB,EAAE;gBACF,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;gBACnC,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,eAAe;gBACf,SAAS;aACV,CAAC;YAEF,uBAAuB;YACvB,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAEvD,6BAA6B;YAC7B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,MAAM,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAE5C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAe;YACxB,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAY,EAAE,CAAC;YAE3B,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7C,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAU,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAe;YACxB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,aAAa,CAAC,CAAC;YAClD,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAU,CAAC;YAExC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,sBAAsB,CAAC,CAAC;YAC3D,CAAC;YAED,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,yBAAyB,CAAC,CAAC;YAC9D,CAAC;YAED,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAE5D,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|