@argonprotocol/localchain 0.0.2

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.
Files changed (4) hide show
  1. package/cli.js +4 -0
  2. package/index.d.ts +624 -0
  3. package/index.js +406 -0
  4. package/package.json +68 -0
package/cli.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ const {runCli} = require('./index.js')
4
+ runCli().catch(console.error);
package/index.d.ts ADDED
@@ -0,0 +1,624 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+ export class AccountStore {
4
+ getDepositAccount(notaryId?: number | undefined | null): Promise<LocalAccount>
5
+ getTaxAccount(notaryId?: number | undefined | null): Promise<LocalAccount>
6
+ get(address: string, accountType: AccountType, notaryId: number): Promise<LocalAccount>
7
+ getById(id: number): Promise<LocalAccount>
8
+ hasAccount(address: string, accountType: AccountType, notaryId: number): Promise<boolean>
9
+ /** Finds an account with no balance that is not waiting for a send claim */
10
+ findIdleJumpAccount(accountType: AccountType, notaryId: number): Promise<LocalAccount | null>
11
+ insert(address: string, accountType: AccountType, notaryId: number, hdPath?: string | undefined | null): Promise<LocalAccount>
12
+ list(includeJumpAccounts?: boolean | undefined | null): Promise<Array<LocalAccount>>
13
+ }
14
+
15
+ export class BalanceChange {
16
+ id: number
17
+ accountId: number
18
+ changeNumber: number
19
+ balance: string
20
+ netBalanceChange: string
21
+ escrowHoldNoteJson?: string
22
+ notaryId: number
23
+ notesJson: string
24
+ proofJson?: string
25
+ finalizedBlockNumber?: number
26
+ status: BalanceChangeStatus
27
+ transactionId?: number
28
+ notarizationId?: number
29
+ }
30
+ export type BalanceChangeRow = BalanceChange
31
+
32
+ export class BalanceChangeBuilder {
33
+ accountType: AccountType
34
+ address: string
35
+ localAccountId: number
36
+ changeNumber: number
37
+ syncStatus?: BalanceChangeStatus
38
+ static newAccount(address: string, localAccountId: number, accountType: AccountType): BalanceChangeBuilder
39
+ isEmptySignature(): Promise<boolean>
40
+ get balance(): Promise<bigint>
41
+ get accountId32(): Promise<Uint8Array>
42
+ isPendingClaim(): Promise<boolean>
43
+ send(amount: bigint, restrictToAddresses?: Array<string> | undefined | null): Promise<void>
44
+ claim(amount: bigint): Promise<ClaimResult>
45
+ claimEscrow(amount: bigint): Promise<ClaimResult>
46
+ claimFromMainchain(transfer: LocalchainTransfer): Promise<void>
47
+ sendToMainchain(amount: bigint): Promise<void>
48
+ createEscrowHold(amount: bigint, dataDomain: string, dataDomainAddress: string, delegatedSignerAddress?: string | undefined | null): Promise<void>
49
+ createPrivateServerEscrowHold(amount: bigint, paymentAddress: string, delegatedSignerAddress?: string | undefined | null): Promise<void>
50
+ sendToVote(amount: bigint): Promise<void>
51
+ /** Lease a data domain. DataDomain leases are converted in full to tax. */
52
+ leaseDataDomain(): Promise<bigint>
53
+ /** Create scale encoded signature message for the balance change. */
54
+ static toSigningMessage(balanceChangeJson: string): Uint8Array
55
+ }
56
+
57
+ export class BalanceChangeStore {
58
+ allForAccount(accountId: number): Promise<Array<BalanceChange>>
59
+ getLatestForAccount(accountId: number): Promise<BalanceChange | null>
60
+ cancel(id: number): Promise<void>
61
+ getById(id: number): Promise<BalanceChange>
62
+ findUnsettled(): Promise<Array<BalanceChange>>
63
+ }
64
+
65
+ export class BalanceSync {
66
+ constructor(localchain: Localchain)
67
+ sync(options?: EscrowCloseOptions | undefined | null): Promise<BalanceSyncResult>
68
+ consolidateJumpAccounts(): Promise<Array<NotarizationTracker>>
69
+ syncUnsettledBalances(): Promise<Array<BalanceChange>>
70
+ syncMainchainTransfers(): Promise<Array<NotarizationTracker>>
71
+ syncBalanceChange(balanceChange: BalanceChange): Promise<BalanceChange>
72
+ processPendingEscrows(options?: EscrowCloseOptions | undefined | null): Promise<Array<NotarizationBuilder>>
73
+ }
74
+
75
+ export class BalanceSyncResult {
76
+ get balanceChanges(): Array<BalanceChange>
77
+ get escrowNotarizations(): Array<NotarizationBuilder>
78
+ get mainchainTransfers(): Array<NotarizationTracker>
79
+ get jumpAccountConsolidations(): Array<NotarizationTracker>
80
+ }
81
+
82
+ export class BalanceTipResult {
83
+ balanceTip: Uint8Array
84
+ notebookNumber: number
85
+ tick: number
86
+ }
87
+
88
+ export class DataDomainLease {
89
+ id: number
90
+ name: string
91
+ tld: string
92
+ registeredToAddress: string
93
+ notarizationId: number
94
+ registeredAtTick: number
95
+ }
96
+ export type DataDomainRow = DataDomainLease
97
+
98
+ export class DataDomainStore {
99
+ static tldFromString(tld: string): DataTLD
100
+ get list(): Promise<Array<DataDomainLease>>
101
+ hashDomain(domain: JsDataDomain): Uint8Array
102
+ static getHash(domain: string): Uint8Array
103
+ static parse(domain: string): DataDomain
104
+ get(id: number): Promise<DataDomainLease>
105
+ }
106
+
107
+ export class Escrow {
108
+ id: string
109
+ initialBalanceChangeJson: string
110
+ notaryId: number
111
+ fromAddress: string
112
+ delegatedSignerAddress?: string
113
+ toAddress: string
114
+ dataDomainHash?: Array<number>
115
+ expirationTick: number
116
+ balanceChangeNumber: number
117
+ notarizationId?: number
118
+ isClient: boolean
119
+ missedClaimWindow: boolean
120
+ get holdAmount(): bigint
121
+ get settledAmount(): bigint
122
+ get settledSignature(): Uint8Array
123
+ isPastClaimPeriod(currentTick: number): boolean
124
+ }
125
+
126
+ export class Keystore {
127
+ useExternal(defaultAddress: string, sign: (address: string, signatureMessage: Uint8Array) => Promise<Uint8Array>, derive: (hdPath: string) => Promise<string>): Promise<void>
128
+ /** Bootstrap this localchain with a new key. Must be empty or will throw an error! Defaults to SR25519 if no scheme is provided. */
129
+ bootstrap(scheme?: CryptoScheme | undefined | null, passwordOption?: KeystorePasswordOption | undefined | null): Promise<string>
130
+ /** Import a known keypair into the embedded keystore. */
131
+ importSuri(suri: string, scheme: CryptoScheme, passwordOption?: KeystorePasswordOption | undefined | null): Promise<string>
132
+ unlock(passwordOption?: KeystorePasswordOption | undefined | null): Promise<void>
133
+ lock(): Promise<void>
134
+ isUnlocked(): Promise<boolean>
135
+ deriveAccountId(hdPath: string): Promise<string>
136
+ sign(address: string, message: Uint8Array): Promise<Uint8Array>
137
+ }
138
+
139
+ export class LocalAccount {
140
+ id: number
141
+ address: string
142
+ hdPath?: string
143
+ accountId32: string
144
+ notaryId: number
145
+ accountType: AccountType
146
+ createdAt: number
147
+ updatedAt: number
148
+ origin?: NotaryAccountOrigin
149
+ }
150
+
151
+ export class Localchain {
152
+ path: string
153
+ static load(config: LocalchainConfig): Promise<Localchain>
154
+ static loadWithoutMainchain(path: string, tickerConfig: TickerConfig, keystorePassword?: KeystorePasswordOption | undefined | null): Promise<Localchain>
155
+ attachMainchain(mainchainClient: MainchainClient): Promise<void>
156
+ updateTicker(ntpSyncPoolUrl?: string | undefined | null): Promise<void>
157
+ close(): Promise<void>
158
+ accountOverview(): Promise<LocalchainOverview>
159
+ static getDefaultDir(): string
160
+ static setDefaultDir(value: string): void
161
+ static getDefaultPath(): string
162
+ get address(): Promise<string>
163
+ get name(): string
164
+ get currentTick(): number
165
+ durationToNextTick(): bigint
166
+ get ticker(): TickerRef
167
+ get keystore(): Keystore
168
+ get mainchainClient(): Promise<MainchainClient | null>
169
+ get mainchainTransfers(): MainchainTransferStore
170
+ get notaryClients(): NotaryClients
171
+ get accounts(): AccountStore
172
+ get balanceChanges(): BalanceChangeStore
173
+ get dataDomains(): DataDomainStore
174
+ get openEscrows(): OpenEscrowsStore
175
+ get balanceSync(): BalanceSync
176
+ get transactions(): Transactions
177
+ beginChange(): NotarizationBuilder
178
+ }
179
+
180
+ export class MainchainClient {
181
+ host: string
182
+ close(): Promise<void>
183
+ static connect(host: string, timeoutMillis: number): Promise<MainchainClient>
184
+ getTicker(): Promise<Ticker>
185
+ getBestBlockHash(): Promise<Uint8Array>
186
+ getVoteBlockHash(currentTick: number): Promise<BestBlockForVote | null>
187
+ getDataDomainRegistration(domainName: string, tld: DataTLD): Promise<DataDomainRegistration | null>
188
+ getDataDomainZoneRecord(domainName: string, tld: DataTLD): Promise<ZoneRecord | null>
189
+ getNotaryDetails(notaryId: number): Promise<NotaryDetails | null>
190
+ getAccount(address: string): Promise<AccountInfo>
191
+ getShares(address: string): Promise<BalancesAccountData>
192
+ getTransferToLocalchainFinalizedBlock(transferId: number): Promise<number | null>
193
+ waitForLocalchainTransfer(transferId: number): Promise<LocalchainTransfer | null>
194
+ getAccountChangesRoot(notaryId: number, notebookNumber: number): Promise<Uint8Array | null>
195
+ latestFinalizedNumber(): Promise<number>
196
+ waitForNotebookImmortalized(notaryId: number, notebookNumber: number): Promise<number>
197
+ }
198
+
199
+ export class MainchainTransferStore {
200
+ sendToLocalchain(amount: bigint, notaryId?: number | undefined | null): Promise<LocalchainTransfer>
201
+ }
202
+
203
+ export class NotarizationBuilder {
204
+ set notaryId(notaryId: number)
205
+ get notaryId(): Promise<number>
206
+ set transaction(transaction: LocalchainTransaction)
207
+ get transaction(): Promise<LocalchainTransaction | null>
208
+ get isFinalized(): Promise<boolean>
209
+ get unclaimedTax(): Promise<bigint>
210
+ get escrows(): Promise<Array<Escrow>>
211
+ get accounts(): Promise<Array<LocalAccount>>
212
+ get balanceChangeBuilders(): Promise<Array<BalanceChangeBuilder>>
213
+ get unusedVoteFunds(): Promise<bigint>
214
+ get unusedDomainFunds(): Promise<bigint>
215
+ get unclaimedDeposits(): Promise<bigint>
216
+ getBalanceChange(account: LocalAccount): Promise<BalanceChangeBuilder>
217
+ addAccount(address: string, accountType: AccountType, notaryId: number): Promise<BalanceChangeBuilder>
218
+ addAccountById(localAccountId: number): Promise<BalanceChangeBuilder>
219
+ getJumpAccount(accountType: AccountType): Promise<BalanceChangeBuilder>
220
+ defaultDepositAccount(): Promise<BalanceChangeBuilder>
221
+ defaultTaxAccount(): Promise<BalanceChangeBuilder>
222
+ loadAccount(account: LocalAccount): Promise<BalanceChangeBuilder>
223
+ canAddEscrow(escrow: OpenEscrow): Promise<boolean>
224
+ cancelEscrow(openEscrow: OpenEscrow): Promise<void>
225
+ claimEscrow(openEscrow: OpenEscrow): Promise<void>
226
+ addVote(vote: BlockVote): Promise<void>
227
+ leaseDataDomain(dataDomain: string, registerToAddress: string): Promise<void>
228
+ /** Calculates the transfer tax on the given amount */
229
+ getTransferTaxAmount(amount: bigint): bigint
230
+ /** Calculates the total needed to end up with the given balance */
231
+ getTotalForAfterTaxBalance(finalBalance: bigint): bigint
232
+ getEscrowTaxAmount(amount: bigint): bigint
233
+ claimFromMainchain(transfer: LocalchainTransfer): Promise<BalanceChangeBuilder>
234
+ claimAndPayTax(milligonsPlusTax: bigint, depositAccountId: number | undefined | null, useDefaultTaxAccount: boolean): Promise<BalanceChangeBuilder>
235
+ fundJumpAccount(milligons: bigint): Promise<BalanceChangeBuilder>
236
+ acceptArgonFileRequest(argonFileJson: string): Promise<void>
237
+ importArgonFile(argonFileJson: string): Promise<void>
238
+ /**
239
+ * Exports an argon file from this notarization builder with the intention that these will be sent to another
240
+ * user (who will import into their own localchain).
241
+ */
242
+ exportAsFile(fileType: ArgonFileType): Promise<string>
243
+ toJSON(): Promise<string>
244
+ notarizeAndWaitForNotebook(): Promise<NotarizationTracker>
245
+ notarize(): Promise<NotarizationTracker>
246
+ verify(): Promise<void>
247
+ sign(): Promise<void>
248
+ }
249
+
250
+ export class NotarizationTracker {
251
+ notebookNumber: number
252
+ tick: number
253
+ notaryId: number
254
+ notarizationId: number
255
+ notarizedBalanceChanges: number
256
+ notarizedVotes: number
257
+ /** Returns the balance changes that were submitted to the notary indexed by the stringified account id (napi doesn't allow numbers as keys) */
258
+ get balanceChangesByAccountId(): Promise<Record<string, BalanceChange>>
259
+ waitForNotebook(): Promise<void>
260
+ /** Asks the notary for proof the transaction was included in a notebook header. If this notebook has not been finalized yet, it will return an error. */
261
+ getNotebookProof(): Promise<Array<NotebookProof>>
262
+ /** Confirms the root added to the mainchain */
263
+ waitForImmortalized(mainchainClient: MainchainClient): Promise<ImmortalizedBlock>
264
+ }
265
+
266
+ export class NotaryClient {
267
+ notaryId: number
268
+ autoVerifyHeaderSignatures: boolean
269
+ isConnected(): Promise<boolean>
270
+ static connect(notaryId: number, publicKey: Uint8Array, host: string, autoVerifyHeaderSignatures: boolean): Promise<NotaryClient>
271
+ getBalanceTip(address: string, accountType: AccountType): Promise<BalanceTipResult>
272
+ get metadata(): Promise<NotebookMeta>
273
+ }
274
+
275
+ export class NotaryClients {
276
+ static new(mainchainClient: MainchainClient): NotaryClients
277
+ close(): Promise<void>
278
+ useClient(client: NotaryClient): Promise<void>
279
+ get(notaryId: number): Promise<NotaryClient>
280
+ }
281
+
282
+ export class OpenEscrow {
283
+ get escrow(): Promise<Escrow>
284
+ sign(settledAmount: bigint): Promise<SignatureResult>
285
+ exportForSend(): Promise<string>
286
+ recordUpdatedSettlement(milligons: bigint, signature: Uint8Array): Promise<void>
287
+ }
288
+
289
+ export class OpenEscrowsStore {
290
+ get(id: string): Promise<OpenEscrow>
291
+ open(escrow: Escrow): OpenEscrow
292
+ getClaimable(): Promise<Array<OpenEscrow>>
293
+ /** Import an escrow from a JSON string. Verifies with the notary that the escrow hold is valid. */
294
+ importEscrow(escrowJson: string): Promise<OpenEscrow>
295
+ /** Create a new escrow as a client. You must first notarize an escrow hold note to the notary for the `client_address`. */
296
+ openClientEscrow(accountId: number): Promise<OpenEscrow>
297
+ }
298
+
299
+ export class OverviewStore {
300
+ get(): Promise<LocalchainOverview>
301
+ }
302
+
303
+ export class TickerRef {
304
+ get current(): number
305
+ tickForTime(timestampMillis: number): number
306
+ timeForTick(tick: number): bigint
307
+ millisToNextTick(): bigint
308
+ get escrowExpirationTicks(): Tick
309
+ }
310
+
311
+ export class Transactions {
312
+ create(transactionType: TransactionType): Promise<LocalchainTransaction>
313
+ request(milligons: bigint): Promise<string>
314
+ createEscrow(escrowMilligons: bigint, recipientAddress: string, dataDomain?: string | undefined | null, notaryId?: number | undefined | null, delegatedSignerAddress?: string | undefined | null): Promise<OpenEscrow>
315
+ send(milligons: bigint, to?: Array<string> | undefined | null): Promise<string>
316
+ importArgons(argonFile: string): Promise<NotarizationTracker>
317
+ acceptArgonRequest(argonFile: string): Promise<NotarizationTracker>
318
+ }
319
+
320
+ export interface AccountInfo {
321
+ nonce: number
322
+ consumers: number
323
+ providers: number
324
+ sufficients: number
325
+ data: BalancesAccountData
326
+ }
327
+
328
+ export enum AccountType {
329
+ Tax = 'tax',
330
+ Deposit = 'deposit'
331
+ }
332
+
333
+ export const ADDRESS_PREFIX: number
334
+
335
+ /** The version of the Argon file format. */
336
+ export const ARGON_FILE_VERSION: string
337
+
338
+ export enum ArgonFileType {
339
+ Send = 0,
340
+ Request = 1
341
+ }
342
+
343
+ export interface BalanceChangeGroup {
344
+ netBalanceChange: bigint
345
+ netTax: bigint
346
+ heldBalance: bigint
347
+ timestamp: number
348
+ notes: Array<string>
349
+ finalizedBlockNumber?: number
350
+ status: BalanceChangeStatus
351
+ notarizationId?: number
352
+ transactionId?: number
353
+ transactionType?: TransactionType
354
+ balanceChanges: Array<BalanceChangeSummary>
355
+ notebookNumber?: number
356
+ }
357
+
358
+ export enum BalanceChangeStatus {
359
+ /** The balance change has been notarized by a notary. It isn't necessarily in a notebook yet. */
360
+ Notarized = 'Notarized',
361
+ /** A balance change that doesn't get final proof because it is one of many in a single notebook. Aka, another balance change superseded it in the notebook. */
362
+ SupersededInNotebook = 'SupersededInNotebook',
363
+ /** Proof has been obtained from a notebook */
364
+ NotebookPublished = 'NotebookPublished',
365
+ /** The mainchain has included the notebook with the balance change */
366
+ Immortalized = 'Immortalized',
367
+ /** A balance change has been sent to another user to claim. Keep checking until it is claimed. */
368
+ WaitingForSendClaim = 'WaitingForSendClaim',
369
+ /** A pending balance change that was canceled before being claimed by another user (escrow or send). */
370
+ Canceled = 'Canceled'
371
+ }
372
+
373
+ export interface BalanceChangeSummary {
374
+ id: number
375
+ finalBalance: bigint
376
+ holdBalance: bigint
377
+ netBalanceChange: bigint
378
+ changeNumber: number
379
+ accountId: number
380
+ accountType: AccountType
381
+ isJumpAccount: boolean
382
+ notes: Array<string>
383
+ status: BalanceChangeStatus
384
+ notebookNumber?: number
385
+ finalizedBlockNumber?: number
386
+ }
387
+
388
+ export interface BalancesAccountData {
389
+ free: bigint
390
+ reserved: bigint
391
+ frozen: bigint
392
+ flags: bigint
393
+ }
394
+
395
+ export interface BestBlockForVote {
396
+ blockHash: Uint8Array
397
+ voteMinimum: bigint
398
+ }
399
+
400
+ export interface BlockVote {
401
+ /** The creator of the seal */
402
+ address: string
403
+ /** The block hash being voted on. Must be in last 2 ticks. */
404
+ blockHash: Array<number>
405
+ /** A unique index per account for this notebook */
406
+ index: number
407
+ /** The voting power of this vote, determined from the amount of tax */
408
+ power: bigint
409
+ /** The data domain used to create this vote */
410
+ dataDomainHash: Array<number>
411
+ /** The data domain payment address used to create this vote */
412
+ dataDomainAddress: string
413
+ /** The mainchain address where rewards will be sent */
414
+ blockRewardsAddress: string
415
+ /** A signature of the vote by the account_id */
416
+ signature: Array<number>
417
+ }
418
+
419
+ export interface ClaimResult {
420
+ claimed: bigint
421
+ tax: bigint
422
+ }
423
+
424
+ export enum CryptoScheme {
425
+ Ed25519 = 0,
426
+ Sr25519 = 1,
427
+ Ecdsa = 2
428
+ }
429
+
430
+ /** Cost to lease a data domain for 1 year */
431
+ export const DATA_DOMAIN_LEASE_COST: bigint
432
+
433
+ /** Minimum data domain name length */
434
+ export const DATA_DOMAIN_MIN_NAME_LENGTH: number
435
+
436
+ export interface DataDomain {
437
+ domainName: string
438
+ topLevelDomain: DataTLD
439
+ }
440
+
441
+ export interface DataDomainRegistration {
442
+ registeredToAddress: string
443
+ registeredAtTick: number
444
+ }
445
+
446
+ /** Max versions that can be in a datastore zone record */
447
+ export const DATASTORE_MAX_VERSIONS: number
448
+
449
+ export enum DataTLD {
450
+ Analytics = 0,
451
+ Automotive = 1,
452
+ Bikes = 2,
453
+ Business = 3,
454
+ Cars = 4,
455
+ Communication = 5,
456
+ Entertainment = 6,
457
+ Finance = 7,
458
+ Flights = 8,
459
+ Health = 9,
460
+ Hotels = 10,
461
+ Jobs = 11,
462
+ News = 12,
463
+ RealEstate = 13,
464
+ Restaurants = 14,
465
+ Shopping = 15,
466
+ Sports = 16,
467
+ Transportation = 17,
468
+ Travel = 18,
469
+ Weather = 19
470
+ }
471
+
472
+ /** Number of ticks past the expiration of an escrow that a recipient has to claim. After this point, sender can recoup the escrowed funds */
473
+ export const ESCROW_CLAWBACK_TICKS: number
474
+
475
+ /** Minimum milligons that can be settled in an escrow */
476
+ export const ESCROW_MINIMUM_SETTLEMENT: bigint
477
+
478
+ export interface EscrowCloseOptions {
479
+ votesAddress?: string
480
+ /** What's the minimum amount of tax we should wait for before voting on blocks */
481
+ minimumVoteAmount?: number
482
+ }
483
+
484
+ export interface ImmortalizedBlock {
485
+ immortalizedBlock: number
486
+ accountChangesMerkleRoot: Uint8Array
487
+ }
488
+
489
+ /**
490
+ * Options to provide the password for a keystore. NOTE that this library cannot clear out memory in javascript.
491
+ * Only a single option should be picked.
492
+ */
493
+ export interface KeystorePasswordOption {
494
+ /** Provides a password directly for the keystore. Converted to a SecretString inside Rust, but not cleared out in javascript or napi. */
495
+ password?: Buffer
496
+ /** Initiate a prompt from the cli to load the password. */
497
+ interactiveCli?: boolean
498
+ /** Load the password from a file. */
499
+ passwordFile?: string
500
+ }
501
+
502
+ export interface LocalchainConfig {
503
+ path: string
504
+ mainchainUrl: string
505
+ ntpPoolUrl?: string
506
+ keystorePassword?: KeystorePasswordOption
507
+ }
508
+
509
+ export interface LocalchainOverview {
510
+ /** The name of this localchain */
511
+ name: string
512
+ /** The primary localchain address */
513
+ address: string
514
+ /** The current account balance */
515
+ balance: bigint
516
+ /** The net pending balance change acceptance/confirmation */
517
+ pendingBalanceChange: bigint
518
+ /** Balance held in escrow */
519
+ heldBalance: bigint
520
+ /** Tax accumulated for the account */
521
+ tax: bigint
522
+ /** The net pending tax balance change */
523
+ pendingTaxChange: bigint
524
+ /** Changes to the account ordered from most recent to oldest */
525
+ changes: Array<BalanceChangeGroup>
526
+ /** The mainchain balance */
527
+ mainchainBalance: bigint
528
+ /** The net pending mainchain balance pending movement in/out of the localchain */
529
+ processingMainchainBalanceChange: bigint
530
+ }
531
+
532
+ export interface LocalchainTransaction {
533
+ id: number
534
+ transactionType: TransactionType
535
+ }
536
+
537
+ export interface LocalchainTransfer {
538
+ address: string
539
+ amount: bigint
540
+ notaryId: number
541
+ expirationTick: number
542
+ transferId: number
543
+ }
544
+
545
+ /** Max balance changes that can be in a single notarization */
546
+ export const NOTARIZATION_MAX_BALANCE_CHANGES: number
547
+
548
+ /** Max notarizations that can be in a single notarization */
549
+ export const NOTARIZATION_MAX_BLOCK_VOTES: number
550
+
551
+ /** Max data domains that can be in a single notarization */
552
+ export const NOTARIZATION_MAX_DOMAINS: number
553
+
554
+ export interface NotaryAccountOrigin {
555
+ notaryId: number
556
+ notebookNumber: number
557
+ accountUid: number
558
+ }
559
+
560
+ export interface NotaryDetails {
561
+ id: number
562
+ hosts: Array<string>
563
+ publicKey: Uint8Array
564
+ }
565
+
566
+ export interface NotebookMeta {
567
+ finalizedNotebookNumber: number
568
+ finalizedTick: number
569
+ }
570
+
571
+ export interface NotebookProof {
572
+ address: string
573
+ accountType: AccountType
574
+ notebookNumber: number
575
+ balance: bigint
576
+ /** H256 hash of the balance tip */
577
+ balanceTip: Uint8Array
578
+ changeNumber: number
579
+ accountOrigin: NotaryAccountOrigin
580
+ escrowHoldNoteJson?: string
581
+ leafIndex: number
582
+ numberOfLeaves: number
583
+ proof: Array<Uint8Array>
584
+ }
585
+
586
+ export declare function runCli(): Promise<void>
587
+
588
+ export interface SignatureResult {
589
+ signature: Uint8Array
590
+ milligons: bigint
591
+ }
592
+
593
+ export interface Ticker {
594
+ tickDurationMillis: number
595
+ genesisUtcTime: number
596
+ }
597
+
598
+ export interface TickerConfig {
599
+ tickDurationMillis: number
600
+ genesisUtcTime: number
601
+ escrowExpirationTicks: number
602
+ ntpPoolUrl?: string
603
+ }
604
+
605
+ export enum TransactionType {
606
+ Send = 0,
607
+ Request = 1,
608
+ OpenEscrow = 2,
609
+ Consolidation = 3
610
+ }
611
+
612
+ export interface VersionHost {
613
+ /** Datastore id is a 2-50 char string that uniquely identifies a data domain. */
614
+ datastoreId: string
615
+ /** The host address where the data domain can be accessed. */
616
+ host: string
617
+ }
618
+
619
+ export interface ZoneRecord {
620
+ paymentAddress: string
621
+ notaryId: number
622
+ /** A mapping of versions to host addresses. */
623
+ versions: Record<string, VersionHost>
624
+ }
package/index.js ADDED
@@ -0,0 +1,406 @@
1
+ // prettier-ignore
2
+ /* eslint-disable */
3
+ /* auto-generated by NAPI-RS */
4
+
5
+ const { readFileSync } = require('fs')
6
+
7
+ let nativeBinding = null
8
+ const loadErrors = []
9
+
10
+ const isMusl = () => {
11
+ let musl = false
12
+ if (process.platform === 'linux') {
13
+ musl = isMuslFromFilesystem()
14
+ if (musl === null) {
15
+ musl = isMuslFromReport()
16
+ }
17
+ if (musl === null) {
18
+ musl = isMuslFromChildProcess()
19
+ }
20
+ }
21
+ return musl
22
+ }
23
+
24
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
25
+
26
+ const isMuslFromFilesystem = () => {
27
+ try {
28
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
29
+ } catch {
30
+ return null
31
+ }
32
+ }
33
+
34
+ const isMuslFromReport = () => {
35
+ const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null
36
+ if (!report) {
37
+ return null
38
+ }
39
+ if (report.header && report.header.glibcVersionRuntime) {
40
+ return false
41
+ }
42
+ if (Array.isArray(report.sharedObjects)) {
43
+ if (report.sharedObjects.some(isFileMusl)) {
44
+ return true
45
+ }
46
+ }
47
+ return false
48
+ }
49
+
50
+ const isMuslFromChildProcess = () => {
51
+ try {
52
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
53
+ } catch (e) {
54
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
55
+ return false
56
+ }
57
+ }
58
+
59
+ function requireNative() {
60
+ if (process.platform === 'android') {
61
+ if (process.arch === 'arm64') {
62
+ try {
63
+ return require('./localchain.android-arm64.node')
64
+ } catch (e) {
65
+ loadErrors.push(e)
66
+ }
67
+ try {
68
+ return require('@argonprotocol/localchain-android-arm64')
69
+ } catch (e) {
70
+ loadErrors.push(e)
71
+ }
72
+
73
+ } else if (process.arch === 'arm') {
74
+ try {
75
+ return require('./localchain.android-arm-eabi.node')
76
+ } catch (e) {
77
+ loadErrors.push(e)
78
+ }
79
+ try {
80
+ return require('@argonprotocol/localchain-android-arm-eabi')
81
+ } catch (e) {
82
+ loadErrors.push(e)
83
+ }
84
+
85
+ } else {
86
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
87
+ }
88
+ } else if (process.platform === 'win32') {
89
+ if (process.arch === 'x64') {
90
+ try {
91
+ return require('./localchain.win32-x64-msvc.node')
92
+ } catch (e) {
93
+ loadErrors.push(e)
94
+ }
95
+ try {
96
+ return require('@argonprotocol/localchain-win32-x64-msvc')
97
+ } catch (e) {
98
+ loadErrors.push(e)
99
+ }
100
+
101
+ } else if (process.arch === 'ia32') {
102
+ try {
103
+ return require('./localchain.win32-ia32-msvc.node')
104
+ } catch (e) {
105
+ loadErrors.push(e)
106
+ }
107
+ try {
108
+ return require('@argonprotocol/localchain-win32-ia32-msvc')
109
+ } catch (e) {
110
+ loadErrors.push(e)
111
+ }
112
+
113
+ } else if (process.arch === 'arm64') {
114
+ try {
115
+ return require('./localchain.win32-arm64-msvc.node')
116
+ } catch (e) {
117
+ loadErrors.push(e)
118
+ }
119
+ try {
120
+ return require('@argonprotocol/localchain-win32-arm64-msvc')
121
+ } catch (e) {
122
+ loadErrors.push(e)
123
+ }
124
+
125
+ } else {
126
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
127
+ }
128
+ } else if (process.platform === 'darwin') {
129
+ try {
130
+ return require('./localchain.darwin-universal.node')
131
+ } catch (e) {
132
+ loadErrors.push(e)
133
+ }
134
+ try {
135
+ return require('@argonprotocol/localchain-darwin-universal')
136
+ } catch (e) {
137
+ loadErrors.push(e)
138
+ }
139
+
140
+ if (process.arch === 'x64') {
141
+ try {
142
+ return require('./localchain.darwin-x64.node')
143
+ } catch (e) {
144
+ loadErrors.push(e)
145
+ }
146
+ try {
147
+ return require('@argonprotocol/localchain-darwin-x64')
148
+ } catch (e) {
149
+ loadErrors.push(e)
150
+ }
151
+
152
+ } else if (process.arch === 'arm64') {
153
+ try {
154
+ return require('./localchain.darwin-arm64.node')
155
+ } catch (e) {
156
+ loadErrors.push(e)
157
+ }
158
+ try {
159
+ return require('@argonprotocol/localchain-darwin-arm64')
160
+ } catch (e) {
161
+ loadErrors.push(e)
162
+ }
163
+
164
+ } else {
165
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
166
+ }
167
+ } else if (process.platform === 'freebsd') {
168
+ if (process.arch === 'x64') {
169
+ try {
170
+ return require('./localchain.freebsd-x64.node')
171
+ } catch (e) {
172
+ loadErrors.push(e)
173
+ }
174
+ try {
175
+ return require('@argonprotocol/localchain-freebsd-x64')
176
+ } catch (e) {
177
+ loadErrors.push(e)
178
+ }
179
+
180
+ } else if (process.arch === 'arm64') {
181
+ try {
182
+ return require('./localchain.freebsd-arm64.node')
183
+ } catch (e) {
184
+ loadErrors.push(e)
185
+ }
186
+ try {
187
+ return require('@argonprotocol/localchain-freebsd-arm64')
188
+ } catch (e) {
189
+ loadErrors.push(e)
190
+ }
191
+
192
+ } else {
193
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
194
+ }
195
+ } else if (process.platform === 'linux') {
196
+ if (process.arch === 'x64') {
197
+ if (isMusl()) {
198
+ try {
199
+ return require('./localchain.linux-x64-musl.node')
200
+ } catch (e) {
201
+ loadErrors.push(e)
202
+ }
203
+ try {
204
+ return require('@argonprotocol/localchain-linux-x64-musl')
205
+ } catch (e) {
206
+ loadErrors.push(e)
207
+ }
208
+
209
+ } else {
210
+ try {
211
+ return require('./localchain.linux-x64-gnu.node')
212
+ } catch (e) {
213
+ loadErrors.push(e)
214
+ }
215
+ try {
216
+ return require('@argonprotocol/localchain-linux-x64-gnu')
217
+ } catch (e) {
218
+ loadErrors.push(e)
219
+ }
220
+
221
+ }
222
+ } else if (process.arch === 'arm64') {
223
+ if (isMusl()) {
224
+ try {
225
+ return require('./localchain.linux-arm64-musl.node')
226
+ } catch (e) {
227
+ loadErrors.push(e)
228
+ }
229
+ try {
230
+ return require('@argonprotocol/localchain-linux-arm64-musl')
231
+ } catch (e) {
232
+ loadErrors.push(e)
233
+ }
234
+
235
+ } else {
236
+ try {
237
+ return require('./localchain.linux-arm64-gnu.node')
238
+ } catch (e) {
239
+ loadErrors.push(e)
240
+ }
241
+ try {
242
+ return require('@argonprotocol/localchain-linux-arm64-gnu')
243
+ } catch (e) {
244
+ loadErrors.push(e)
245
+ }
246
+
247
+ }
248
+ } else if (process.arch === 'arm') {
249
+ if (isMusl()) {
250
+ try {
251
+ return require('./localchain.linux-arm-musleabihf.node')
252
+ } catch (e) {
253
+ loadErrors.push(e)
254
+ }
255
+ try {
256
+ return require('@argonprotocol/localchain-linux-arm-musleabihf')
257
+ } catch (e) {
258
+ loadErrors.push(e)
259
+ }
260
+
261
+ } else {
262
+ try {
263
+ return require('./localchain.linux-arm-gnueabihf.node')
264
+ } catch (e) {
265
+ loadErrors.push(e)
266
+ }
267
+ try {
268
+ return require('@argonprotocol/localchain-linux-arm-gnueabihf')
269
+ } catch (e) {
270
+ loadErrors.push(e)
271
+ }
272
+
273
+ }
274
+ } else if (process.arch === 'riscv64') {
275
+ if (isMusl()) {
276
+ try {
277
+ return require('./localchain.linux-riscv64-musl.node')
278
+ } catch (e) {
279
+ loadErrors.push(e)
280
+ }
281
+ try {
282
+ return require('@argonprotocol/localchain-linux-riscv64-musl')
283
+ } catch (e) {
284
+ loadErrors.push(e)
285
+ }
286
+
287
+ } else {
288
+ try {
289
+ return require('./localchain.linux-riscv64-gnu.node')
290
+ } catch (e) {
291
+ loadErrors.push(e)
292
+ }
293
+ try {
294
+ return require('@argonprotocol/localchain-linux-riscv64-gnu')
295
+ } catch (e) {
296
+ loadErrors.push(e)
297
+ }
298
+
299
+ }
300
+ } else if (process.arch === 'ppc64') {
301
+ try {
302
+ return require('./localchain.linux-ppc64-gnu.node')
303
+ } catch (e) {
304
+ loadErrors.push(e)
305
+ }
306
+ try {
307
+ return require('@argonprotocol/localchain-linux-ppc64-gnu')
308
+ } catch (e) {
309
+ loadErrors.push(e)
310
+ }
311
+
312
+ } else if (process.arch === 's390x') {
313
+ try {
314
+ return require('./localchain.linux-s390x-gnu.node')
315
+ } catch (e) {
316
+ loadErrors.push(e)
317
+ }
318
+ try {
319
+ return require('@argonprotocol/localchain-linux-s390x-gnu')
320
+ } catch (e) {
321
+ loadErrors.push(e)
322
+ }
323
+
324
+ } else {
325
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
326
+ }
327
+ } else {
328
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
329
+ }
330
+ }
331
+
332
+ nativeBinding = requireNative()
333
+
334
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
335
+ try {
336
+ nativeBinding = require('./localchain.wasi.cjs')
337
+ } catch (err) {
338
+ if (process.env.NAPI_RS_FORCE_WASI) {
339
+ console.error(err)
340
+ }
341
+ }
342
+ if (!nativeBinding) {
343
+ try {
344
+ nativeBinding = require('@argonprotocol/localchain-wasm32-wasi')
345
+ } catch (err) {
346
+ if (process.env.NAPI_RS_FORCE_WASI) {
347
+ console.error(err)
348
+ }
349
+ }
350
+ }
351
+ }
352
+
353
+ if (!nativeBinding) {
354
+ if (loadErrors.length > 0) {
355
+ // TODO Link to documentation with potential fixes
356
+ // - The package owner could build/publish bindings for this arch
357
+ // - The user may need to bundle the correct files
358
+ // - The user may need to re-install node_modules to get new packages
359
+ throw new Error('Failed to load native binding', { cause: loadErrors })
360
+ }
361
+ throw new Error(`Failed to load native binding`)
362
+ }
363
+
364
+ module.exports.AccountStore = nativeBinding.AccountStore
365
+ module.exports.BalanceChange = nativeBinding.BalanceChange
366
+ module.exports.BalanceChangeRow = nativeBinding.BalanceChangeRow
367
+ module.exports.BalanceChangeBuilder = nativeBinding.BalanceChangeBuilder
368
+ module.exports.BalanceChangeStore = nativeBinding.BalanceChangeStore
369
+ module.exports.BalanceSync = nativeBinding.BalanceSync
370
+ module.exports.BalanceSyncResult = nativeBinding.BalanceSyncResult
371
+ module.exports.BalanceTipResult = nativeBinding.BalanceTipResult
372
+ module.exports.DataDomainLease = nativeBinding.DataDomainLease
373
+ module.exports.DataDomainRow = nativeBinding.DataDomainRow
374
+ module.exports.DataDomainStore = nativeBinding.DataDomainStore
375
+ module.exports.Escrow = nativeBinding.Escrow
376
+ module.exports.Keystore = nativeBinding.Keystore
377
+ module.exports.LocalAccount = nativeBinding.LocalAccount
378
+ module.exports.Localchain = nativeBinding.Localchain
379
+ module.exports.MainchainClient = nativeBinding.MainchainClient
380
+ module.exports.MainchainTransferStore = nativeBinding.MainchainTransferStore
381
+ module.exports.NotarizationBuilder = nativeBinding.NotarizationBuilder
382
+ module.exports.NotarizationTracker = nativeBinding.NotarizationTracker
383
+ module.exports.NotaryClient = nativeBinding.NotaryClient
384
+ module.exports.NotaryClients = nativeBinding.NotaryClients
385
+ module.exports.OpenEscrow = nativeBinding.OpenEscrow
386
+ module.exports.OpenEscrowsStore = nativeBinding.OpenEscrowsStore
387
+ module.exports.OverviewStore = nativeBinding.OverviewStore
388
+ module.exports.TickerRef = nativeBinding.TickerRef
389
+ module.exports.Transactions = nativeBinding.Transactions
390
+ module.exports.AccountType = nativeBinding.AccountType
391
+ module.exports.ADDRESS_PREFIX = nativeBinding.ADDRESS_PREFIX
392
+ module.exports.ARGON_FILE_VERSION = nativeBinding.ARGON_FILE_VERSION
393
+ module.exports.ArgonFileType = nativeBinding.ArgonFileType
394
+ module.exports.BalanceChangeStatus = nativeBinding.BalanceChangeStatus
395
+ module.exports.CryptoScheme = nativeBinding.CryptoScheme
396
+ module.exports.DATA_DOMAIN_LEASE_COST = nativeBinding.DATA_DOMAIN_LEASE_COST
397
+ module.exports.DATA_DOMAIN_MIN_NAME_LENGTH = nativeBinding.DATA_DOMAIN_MIN_NAME_LENGTH
398
+ module.exports.DATASTORE_MAX_VERSIONS = nativeBinding.DATASTORE_MAX_VERSIONS
399
+ module.exports.DataTLD = nativeBinding.DataTLD
400
+ module.exports.ESCROW_CLAWBACK_TICKS = nativeBinding.ESCROW_CLAWBACK_TICKS
401
+ module.exports.ESCROW_MINIMUM_SETTLEMENT = nativeBinding.ESCROW_MINIMUM_SETTLEMENT
402
+ module.exports.NOTARIZATION_MAX_BALANCE_CHANGES = nativeBinding.NOTARIZATION_MAX_BALANCE_CHANGES
403
+ module.exports.NOTARIZATION_MAX_BLOCK_VOTES = nativeBinding.NOTARIZATION_MAX_BLOCK_VOTES
404
+ module.exports.NOTARIZATION_MAX_DOMAINS = nativeBinding.NOTARIZATION_MAX_DOMAINS
405
+ module.exports.runCli = nativeBinding.runCli
406
+ module.exports.TransactionType = nativeBinding.TransactionType
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@argonprotocol/localchain",
3
+ "version": "0.0.2",
4
+ "description": "A nodejs binding to the Argon Localchain",
5
+ "bin": "cli.js",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/argonprotocol/mainchain.git"
12
+ },
13
+ "homepage": "https://argonprotocol.org",
14
+ "scripts": {
15
+ "artifacts": "napi artifacts",
16
+ "build": "napi build --platform --release --no-const-enum --features=napi -p argon-localchain",
17
+ "build:debug": "napi build --platform --no-const-enum --features=napi -p argon-localchain",
18
+ "prepublishOnly": "napi prepublish -t npm",
19
+ "pretest": "npm run build:debug",
20
+ "test": "npm run pretest && cd .. && jest --testTimeout=60000",
21
+ "version": "napi version"
22
+ },
23
+ "license": "MIT",
24
+ "main": "index.js",
25
+ "types": "index.d.ts",
26
+ "napi": {
27
+ "binaryName": "localchain",
28
+ "packageName": "@argonprotocol/localchain",
29
+ "targets": [
30
+ "x86_64-apple-darwin",
31
+ "aarch64-apple-darwin",
32
+ "x86_64-pc-windows-msvc",
33
+ "x86_64-unknown-linux-gnu",
34
+ "aarch64-unknown-linux-gnu"
35
+ ]
36
+ },
37
+ "devDependencies": {
38
+ "@argonprotocol/mainchain": "0.0.2",
39
+ "@napi-rs/cli": "3.0.0-alpha.55",
40
+ "@polkadot/util": "^13.0.2",
41
+ "@polkadot/util-crypto": "^13.0.2",
42
+ "@polkadot/wasm-crypto": "^7.3.2",
43
+ "@types/http-proxy": "^1.17.14",
44
+ "@types/jest": "^29.5.11",
45
+ "@types/node": "^18.19.6",
46
+ "@types/pg": "^8.10.9",
47
+ "http-proxy": "^1.18.1",
48
+ "jest": "^29.7.0",
49
+ "nanoid": "^3.3.7",
50
+ "pg": "^8.11.3",
51
+ "portfinder": "^1.0.32",
52
+ "shx": "^0.3.4",
53
+ "ts-jest": "^29.1.2",
54
+ "tslib": "^2.6.2",
55
+ "typescript": "^5.3.3"
56
+ },
57
+ "engines": {
58
+ "node": ">= 18"
59
+ },
60
+ "packageManager": "yarn@4.1.0",
61
+ "optionalDependencies": {
62
+ "@argonprotocol/localchain-darwin-x64": "0.0.2",
63
+ "@argonprotocol/localchain-darwin-arm64": "0.0.2",
64
+ "@argonprotocol/localchain-win32-x64-msvc": "0.0.2",
65
+ "@argonprotocol/localchain-linux-x64-gnu": "0.0.2",
66
+ "@argonprotocol/localchain-linux-arm64-gnu": "0.0.2"
67
+ }
68
+ }