Skip to content

Provider and Signer

ootle.ts separates concerns into two interfaces: Provider (reads) and Signer (writes). This separation lets you swap implementations without changing application code.

A Provider gives read-only access to the Ootle network:

interface Provider {
getSubstate(id: string): Promise<IndexerGetSubstateResponse>;
fetchSubstates(ids: string[]): Promise<GetSubstatesResponse>;
listRecentTransactions(params: ListRecentTransactionsRequest): Promise<ListRecentTransactionsResponse>;
getTemplateDefinition(address: string): Promise<GetTemplateDefinitionResponse>;
submitTransaction(envelope: TransactionEnvelope): Promise<IndexerSubmitTransactionResponse>;
getTransactionResult(txId: string): Promise<IndexerGetTransactionResultResponse>;
}

The SDK ships one implementation: IndexerProvider (in @tari-project/ootle-indexer), which wraps the indexer REST API.

A Signer holds or delegates access to a secret key:

interface Signer {
getAddress(): Promise<string>;
getPublicKey(): Promise<Uint8Array>;
signTransaction(unsignedTx: UnsignedTransactionV1): Promise<TransactionSignature[]>;
}

Two implementations are provided:

ClassPackageKey location
WalletDaemonSignerootle-wallet-daemon-signerOn a separate daemon process
SecretKeyWalletootle-secret-key-walletIn JavaScript memory (testing only)
┌─────────────┐
│ Your App │
└──────┬──────┘
┌──────────────┼──────────────┐
▼ ▼ ▼
TransactionBuilder Provider Signer
(build instructions) (read state) (sign tx)
│ │ │
└──────────────┼──────────────┘
sendTransaction(provider, signer, unsignedTx)

The sendTransaction helper chains resolve → sign → submit → watch into a single call. You can also call each step individually for more control.