Repository: onflow/fcl-js

Issue:
Centralize and Migrate SDK Types
Make the SDK package fully TypeScript-compliant. Establish it as the single source of truth for essential types so that other packages can reference them consistently.

Discussion:

Solution patch:
diff --git a/.changeset/tame-pianos-doubt.md b/.changeset/tame-pianos-doubt.md
new file mode 100644
index 00000000..f4d0f2b5
--- /dev/null
+++ b/.changeset/tame-pianos-doubt.md
@@ -0,0 +1,6 @@
+---
+"@onflow/typedefs": minor
+"@onflow/sdk": minor
+---
+
+Refactored onflow/sdk package to improve TypeScript support
diff --git a/packages/sdk/package.json b/packages/sdk/package.json
index f4997dca..7778f340 100644
--- a/packages/sdk/package.json
+++ b/packages/sdk/package.json
@@ -45,6 +45,7 @@
     "@onflow/rlp": "1.2.3",
     "@onflow/transport-http": "1.12.0",
     "@onflow/typedefs": "1.5.0",
+    "@onflow/types": "1.4.1",
     "@onflow/util-actor": "1.3.4",
     "@onflow/util-address": "1.2.3",
     "@onflow/util-invariant": "1.2.4",
diff --git a/packages/sdk/readme.md b/packages/sdk/readme.md
index dd52105e..b34d3200 100644
--- a/packages/sdk/readme.md
+++ b/packages/sdk/readme.md
@@ -23,13 +23,13 @@ npm install --save @onflow/sdk
 
 Welcome, we're glad you're here.
 
-The Flow JS-SDK is a relatively low-level suite of tools that allow JavaScript applications to interact with the Flow Blockchain.
+The Flow JS-SDK is a relatively low-level suite of tools that allow JavaScript and TypeScript applications to interact with the Flow Blockchain.
 
 In doing so, the Flow JS-SDK employs several concepts which empower developers to create, and operate upon what we call _Interactions_ that can be sent to the Flow Blockchain, and what we call _Responses_ that are returned from the Flow Blockchain.
 
 Interactions have a Type, which tells the Flow JS-SDK itself how to react to preparing, operating upon and sending this specific interaction. Types of Interactions include, Get Account, Execute Script, Execute Transaction, Get Events, Get Latest Block and Get Transaction Status.
 
-Further in this document we will outline how to create such Interactions for use in your JavaScript applications, and how to deal with the Responses that the Flow Blockchain returns.
+Further in this document we will outline how to create such Interactions for use in your TypeScript or JavaScript applications, and how to deal with the Responses that the Flow Blockchain returns.
 
 ## Phases
 
@@ -45,9 +45,9 @@ Build is the phase of your use of the Flow JS-SDK where you _Build_ up a specifi
 
 The Flow JS-SDK exposes what we call a _build_ function, and a suite of _builder_ functions. The build function consumes as its argument an array of builder functions within it. Each builder function consumes information that you know, and that you want to place into the interaction.
 
-Example 1
-    : Building an Execute Script Interaction
-```javascript
+Example 1: Building an Execute Script Interaction
+
+```typescript
 import * as sdk from "@onflow/sdk"
 
 const interaction = await sdk.build([
@@ -61,13 +61,13 @@ const interaction = await sdk.build([
 
 In Example 1, we're composing an Execute Script Interaction, because we have built an interaction and specified a Script Cadence code within it using the sdk.script builder.
 
-Example 2
-    : Building an Execute Get Account Interaction
-```javascript
+Example 2: Building an Execute Get Account Interaction
+
+```typescript
 import * as sdk from "@onflow/sdk"
 
 const interaction = await sdk.build([
-   sdk.getAccount("123ABC456DEF")
+   sdk.getAccount("0x123ABC456DEF")
 ])
 ```
 
@@ -87,21 +87,21 @@ The builders for the Proposer, Payer and each Authorizer consume an _authorizati
 
 The Address for an Authorization corresponds to the address for the Flow Account this authorization represents. The Signing Function is a function which can produce a Signature for a transaction on behalf of the specified account. The keyId represents the id of the key on the Account which needs to be used to produce the Signature for a transaction. An Authorization also optionally takes a sequence number, which is the sequence number for the key corresponding to the keyId of the Flow Account this authorization represents, if this authorization is for a proposer. (Again, more on this later. Observe how we choose not to provide this piece of information in Example 3, this decision will be explained later).
 
-Example 3
-    : Building a Transaction Interaction
-```javascript
+Example 3: Building a Transaction Interaction
+
+```typescript
 import * as sdk from "@onflow/sdk"
 
-const signingFunction = (...) => {
-    ...
-    return signature
+const signingFunction = (message) => {
+    // Signing logic would go here
+    return { signature: "generated-signature" }
 }
 
 const interaction = await sdk.build([
     sdk.transaction`transaction() { prepare(acct: AuthAccount) {} execute { log("Hello, Flow!") } }`,
-    sdk.payer(sdk.authorization("f8d6e0586b0a20c7", signingFunction, 0)),
-    sdk.proposer(sdk.authorization("f8d6e0586b0a20c7", signingFunction, 0)),
-    sdk.authorizations([sdk.authorization("f8d6e0586b0a20c7", signingFunction, 0)]),
+    sdk.payer(sdk.authorization("0xf8d6e0586b0a20c7", signingFunction, 0)),
+    sdk.proposer(sdk.authorization("0xf8d6e0586b0a20c7", signingFunction, 0)),
+    sdk.authorizations([sdk.authorization("0xf8d6e0586b0a20c7", signingFunction, 0)]),
 ])
 ```
 
@@ -115,11 +115,11 @@ Some things, however, we don't know. For example, when developing your dApp, you
 
 This is where the _Resolve_ phase comes in. Resolve takes your built interaction containing all the information you do know and does its best to get it into a position where it can be sent to the Flow Blockchain. The Flow JS-SDK comes with several _resolver_ functions that your dApp can use to do just this.
 
-Example 4
-    : Building an Execute Script Interaction
-```javascript
+Example 4: Building an Execute Script Interaction
+
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
+import { t } from "@onflow/sdk"
 
 const builtInteraction = await sdk.build([
     sdk.script`
@@ -127,7 +127,7 @@ const builtInteraction = await sdk.build([
             return "Hello, Flow!"
         }
     `,
-    sdk.args([ sdk.arg("Hello, Flow", types.String) ])
+    sdk.args([ sdk.arg("Hello, Flow", t.String) ])
 ])
 
 const resolvedInteraction = await sdk.pipe(builtInteraction, [
@@ -138,23 +138,22 @@ const resolvedInteraction = await sdk.pipe(builtInteraction, [
 
 In Example 4 we Build an Execute Script Interaction by using the script builder to specify a Cadence script and the args and arg builders to specify some arguments to pass into the Cadence Script. To Resolve this built interaction, we pipe'd the built interaction through an array of resolvers. The resolveParams resolver encoded the Cadence script into a format the Flow Blockchain accepts, and the resolveArguments resolver prepared the arguments into the correct encoding that the Flow Blockchain accepts.
 
-Example 5
-    : Building a Transaction Interaction
-```javascript
+Example 5: Building a Transaction Interaction
+
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
 
-const signingFunction = (...) => {
-    ...
-    return signature
+const signingFunction = (message) => {
+    // Signing logic would go here
+    return { signature: "generated-signature" }
 }
 
 const builtInteraction = await sdk.build([
     sdk.transaction`transaction(msg: String) { prepare(acct: AuthAccount) {} execute { log(msg) } }`,
     sdk.args([sdk.arg("Hello, Flow!", types.String)]),
-    sdk.payer(sdk.authorization("f8d6e0586b0a20c7", signingFunction, 0)),
-    sdk.proposer(sdk.authorization("f8d6e0586b0a20c7", signingFunction, 0)),
-    sdk.authorizations([sdk.authorization("f8d6e0586b0a20c7", signingFunction, 0)]),
+    sdk.payer(sdk.authorization("0xf8d6e0586b0a20c7", signingFunction, 0)),
+    sdk.proposer(sdk.authorization("0xf8d6e0586b0a20c7", signingFunction, 0)),
+    sdk.authorizations([sdk.authorization("0xf8d6e0586b0a20c7", signingFunction, 0)]),
 ])
 
 const resolvedInteraction = await sdk.pipe(builtInteraction, [
@@ -175,11 +174,11 @@ After the Transaction Interaction is built, we pipe it through a series of resol
 
 Once an Interaction has been _Built_ and, if necessary, _Resolved_ it can then be _Sent_ to the Flow Blockchain. Fortunately, sending to the Flow Blockchain is simple. The Flow JS-SDK exposes a Send function which consumes an Interaction and some configuration, and returns a data structure called a _Response_ (more on this later).
 
-Example 6
-    : Sending an Execute Script Interaction
-```javascript
+Example 6: Sending an Execute Script Interaction
+
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
+import { t } from "@onflow/sdk"
 
 const builtInteraction = await sdk.build([
     sdk.script`
@@ -187,7 +186,7 @@ const builtInteraction = await sdk.build([
             return "Hello, Flow!"
         }
     `,
-    sdk.args([ sdk.arg("Hello, Flow", types.String) ])
+    sdk.args([ sdk.arg("Hello, Flow", t.String) ])
 ])
 
 const resolvedInteraction = await sdk.pipe(builtInteraction, [
@@ -195,6 +194,7 @@ const resolvedInteraction = await sdk.pipe(builtInteraction, [
     sdk.resolveArguments,
 ])
 
+// The response contains the raw result from the access node
 const response = await sdk.send(resolvedInteraction, { node: "my-access-node-url" })
 ```
 
@@ -215,11 +215,11 @@ For the available Interaction types, decoding responses for them produces values
 - Decoding a Get Transaction Status interaction returns a JavaScript object of relevant information about the status of a transaction.
 - Decoding a Get Latest Block interaction returns a JavaScript object of relevant information of the Latest Block.
 
-Example 7
-    : Decoding an Execute Script Interaction
-```javascript
+Example 7: Decoding an Execute Script Interaction
+
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
+import { t } from "@onflow/sdk"
 
 const builtInteraction = await sdk.build([
     sdk.script`
@@ -227,7 +227,7 @@ const builtInteraction = await sdk.build([
             return int1 + int2
         }
     `,
-    sdk.args([ sdk.arg(1, types.Int), sdk.arg(2, types.Int) ])
+    sdk.args([ sdk.arg(1, t.Int), sdk.arg(2, t.Int) ])
 ])
 
 const resolvedInteraction = await sdk.pipe(builtInteraction, [
@@ -239,8 +239,8 @@ const response = await sdk.send(resolvedInteraction, { node: "my-access-node-url
 
 const decoded = await sdk.decode(response)
 
-assert(3 === decoded)
-assert(typeof decoded === "number")
+console.assert(3 === decoded)
+console.assert(typeof decoded === "number")
 ```
 
 In Example 7 we illustrate how intuitively the decoded value returned from calling decode on the response returned from this Execute Script interaction must be the JavaScript number 3. This is because the Execute Script interaction contains Cadence code, which when executed with the included script arguments, adds the Cadence Integer 1 and Cadence Integer 2 together to return the Cadence Integer 3. Since there is no native concept of a Cadence Integer of value 3 in JavaScript, when this response is decoded, we intuitively expect the decoded value to be the JavaScript number 3.
@@ -253,11 +253,11 @@ Custom Decoders are a concept available in the Flow JS-SDK which allows develope
 
 Custom Decoders are declared by passing a configuration object of key value pairs into the decode function. The keys included in this object correspond to the Cadence type you wish to provide a custom decoder for, and the value must be an asynchronous function which returns your desired JavaScript value for the type. The keys in this object can optionally be regex values declared by writing a regular expression between two forward slashes (ie: "/my-regex-exp/").
 
-Example 8
-    : Using a Custom Decoder to decode an Execute Script interaction.
-```javascript
+Example 8: Using a Custom Decoder to decode an Execute Script interaction.
+
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
+import { t } from "@onflow/sdk"
 
 const builtInteraction = await sdk.build([
     sdk.script`
@@ -275,7 +275,7 @@ const builtInteraction = await sdk.build([
             return Point(x: x, y: y)
         }
     `,
-    sdk.args([ sdk.arg(123, types.Int), sdk.arg(456, types.Int) ])
+    sdk.args([ sdk.arg(123, t.Int), sdk.arg(456, t.Int) ])
 ])
 
 const resolvedInteraction = await sdk.pipe(builtInteraction, [
@@ -285,20 +285,31 @@ const resolvedInteraction = await sdk.pipe(builtInteraction, [
 
 const response = await sdk.send(resolvedInteraction, { node: "my-access-node-url" })
 
-class Point {
-    constructor({ x, y }) {
-        this.x = x
-        this.y = y
-        this.created_at = Date.now()
+// Create a custom type that we'll convert our Point into
+interface PointInterface {
+    x: number;
+    y: number;
+}
+
+class Point implements PointInterface {
+    x: number;
+    y: number;
+    created_at: number;
+
+    constructor({ x, y }: PointInterface) {
+        this.x = x;
+        this.y = y;
+        this.created_at = Date.now();
     }
 }
 
-const decoded = await sdk.decode(response, {
-    "/Point/": async point => new Point(point)
+const decoded: Point = await sdk.decode(response, {
+    "/Point/": async (point: PointInterface) => new Point(point)
 })
 
-assert(3 === decoded)
-assert(typeof decoded === "number")
+console.assert(decoded.x === 123);
+console.assert(decoded.y === 456);
+console.assert(decoded instanceof Point);
 ```
 
 In Example 8 we declare an Execute Script interaction with Cadence code that returns a Point Cadence struct. If no custom decoders were declared, the returned Cadence Point struct would by default be decoded into a JavaScript object with key value pairs for its x and y variables. However, in this example we declare a custom decoder onto the call to decode which includes a regular expression that will match to the Point struct and return a new instance of the Point class that is declared just above.
@@ -309,15 +320,24 @@ In Example 8 we declare an Execute Script interaction with Cadence code that ret
 
 Building an interaction produces an unresolved interaction. For example, to build a transaction interaction you must call `sdk.build([...])`, and pass in the sequence of builders you want to use to compose that transaction interaction. The example below highlights one way to build a transaction interaction:
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
+import { t } from "@onflow/sdk"
+
+const signingFunction = (message) => {
+    // Signing logic would go here
+    return { signature: "generated-signature" }
+}
+
+// Optional: define a specific sequence number
+const seqNum: number = 42
+
 const builtTxIx = await sdk.build([
   sdk.transaction`transaction(msg: String) { prepare(acct: AuthAccount) {} execute { log(msg) } }`,
-  sdk.args([sdk.arg("Hello, Flow!", types.String)]),
-  sdk.payer(sdk.authorization("01", signingFunction, 0)),
-  sdk.proposer(sdk.authorization("01", signingFunction, 0, seqNum)),
-  sdk.authorizations([sdk.authorization("01", signingFunction, 0)]),
+  sdk.args([sdk.arg("Hello, Flow!", t.String)]),
+  sdk.payer(sdk.authorization("0x01", signingFunction, 0)),
+  sdk.proposer(sdk.authorization("0x01", signingFunction, 0, seqNum)),
+  sdk.authorizations([sdk.authorization("0x01", signingFunction, 0)]),
 ])
 ```
 
@@ -325,8 +345,9 @@ const builtTxIx = await sdk.build([
 
 Once a transaction interaction is built, it's still not quite ready to be sent to the Access Node. To further prepare it to be ready to be sent to the Access Node, you must resolve it by piping it through a series of resolvers. Resolvers are functions that consume an interaction and attempt to fill in or prepare any missing pieces of it to get it ready to be sent to the Access API. The example below highlights one way to resolve a transaction interaction:
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
+
 const resolvedTxIx = await sdk.pipe(builtTxIx, [
   sdk.resolve([
     sdk.resolveArguments,
@@ -336,16 +357,25 @@ const resolvedTxIx = await sdk.pipe(builtTxIx, [
     sdk.resolveRefBlockId({ node: "http://localhost:8080" }),
     sdk.resolveSignatures
   ])
-)
+])
 ```
 
 ### Example: Sending A Transaction Interaction
 
 Now that your transaction interaction is resolved, it can be sent to an Access Node! To send it to an Access Node, you must call `sdk.send(...)` with that interaction, and a configuration object. To specify which Access Node to send your request to, you specify it in the _node_ parameter of the config object. For example, the code below shows how to send your transaction interaction to the Flow Emulator running on _localhost:8080_:
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-const response = await sdk.send(resolvedTxIx, { node: "http://localhost:8080" })
+
+const options = { 
+  node: "http://localhost:8080" 
+}
+
+const response = await sdk.send(resolvedTxIx, options)
+
+// You can then decode the response to get the transaction ID
+const txId: string = await sdk.decode(response)
+console.log("Transaction ID:", txId)
 ```
 
 The SDK additionally supplies builders to construct interactions of many different types to interact with the Access Node's various APIs.
@@ -356,23 +386,36 @@ Please reference the provided example project `react-simple` for example code.
 
 As an extension, it is possible to intercept the voucher before sending a transaction. To do this, use `sdk.voucherIntercept(...)`. This argument is an arbitrary async function that receives a voucher object containing information about the transaction before it is sent. Within this, you can call `sdk.voucherToTxId(voucher)` to get the txId. Furthermore, you can call any API to record this txId before sending the transaction. If an error is thrown in this, the transaction sending process will be aborted.
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
+import { t } from "@onflow/sdk"
+
+// Example function to send transaction hash to your backend API
+async function sendHashToBackend(txId: string) {
+  // Your backend API call logic here
+  console.log(`Sending hash ${txId} to backend`);
+}
+
+// Define signing function
+const signingFunction = () => ({ signature: "generated-signature" });
+const seqNum: number = 42; // Optional: define a specific sequence number
+
 const response = await sdk.send(
   await sdk.resolve(
     await sdk.build([
       sdk.transaction`transaction(msg: String) { prepare(acct: AuthAccount) {} execute { log(msg) } }`,
       sdk.args([sdk.arg("Hello, Flow!", types.String)]),
-      sdk.payer(sdk.authorization("01", signingFunction, 0)),
-      sdk.proposer(sdk.authorization("01", signingFunction, 0, seqNum)),
-      sdk.authorizations([sdk.authorization("01", signingFunction, 0)]),
-      sdk.voucherIntercept(async voucher => {
-        const txId = sdk.voucherToTxId(voucher)
+      sdk.payer(sdk.authorization("0x01", signingFunction, 0)),
+      sdk.proposer(sdk.authorization("0x01", signingFunction, 0, seqNum)),
+      sdk.authorizations([sdk.authorization("0x01", signingFunction, 0)]),
+      sdk.voucherIntercept(async (voucher: any) => {
+        const txId: string = sdk.voucherToTxId(voucher)
 
-        // you can make an async to your backend to keep track of the hash
+        // You can make an async call to your backend to keep track of the hash
         await sendHashToBackend(txId)
 
-        // could throw an error here if you wanted which would halt the transaction.
+        // Could throw an error here if you wanted which would halt the transaction.
+        // if (someCondition) throw new Error("Transaction aborted due to condition");
       }),
     ])
   ), { node: "http://localhost:8080" })
@@ -380,102 +423,185 @@ const response = await sdk.send(
 
 ### GetAccount Usage
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-const response = await sdk.send(await sdk.build([
-  sdk.getAccount(addr)
-]), { node: "http://localhost:8080" })
+
+// Build and resolve the interaction
+const interaction = await sdk.build([
+  sdk.getAccount("0xf8d6e0586b0a20c7")
+])
+
+// Send the interaction to the Access Node
+const response = await sdk.send(interaction, { node: "http://localhost:8080" })
+const account = await sdk.decode(response)
+console.log("Account balance:", account.balance)
 ```
 
 ### GetEvents Usage
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-const response = await sdk.send(await sdk.build([
+
+// Event type and block range
+const eventType: string = "A.1654653399040a61.FlowToken.TokensDeposited"
+const startBlock: number = 10000
+const endBlock: number = 10100
+
+// Build and resolve the interaction
+const interaction = await sdk.build([
   sdk.getEvents(eventType, startBlock, endBlock),
-]), { node: "http://localhost:8080" })
+])
+
+// Send the interaction to the Access Node
+const response = await sdk.send(interaction, { node: "http://localhost:8080" })
+const events = await sdk.decode(response)
+console.log(`Got ${events.length} events`)
 ```
 
 ### GetLatestBlock Usage
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-const response = await sdk.send(await sdk.build([
-  sdk.getLatestBlock()
-]), { node: "http://localhost:8080" })
+
+// Build the interaction, specify whether to get sealed blocks or not
+const interaction = await sdk.build([
+  sdk.getLatestBlock(true) // true for sealed blocks, false for unsealed
+])
+
+// Send the interaction to the Access Node
+const response = await sdk.send(interaction, { node: "http://localhost:8080" })
+const block = await sdk.decode(response)
+console.log(`Latest block height: ${block.height}`)
 ```
 
 ### GetTransactionStatus Usage
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-const response = await sdk.send(await sdk.build([
+
+// Transaction ID to check
+const txId: string = "9dda49b2f2b1b9bc12d5cabe09f8a8cb49828c9c449574c1f46f3b3a5e5c0cb0"
+
+// Build the interaction
+const interaction = await sdk.build([
   sdk.getTransactionStatus(txId)
-]), { node: "http://localhost:8080" })
+])
+
+// Send the interaction to the Access Node
+const response = await sdk.send(interaction, { node: "http://localhost:8080" })
+const status = await sdk.decode(response)
+console.log(`Transaction status: ${status.statusString}`)
 ```
 
 ### Ping Usage
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-const response = await sdk.send(await sdk.build([
+
+// Build the interaction
+const interaction = await sdk.build([
   sdk.ping()
-]), { node: "http://localhost:8080" })
+])
+
+// Send the interaction to the Access Node
+const response = await sdk.send(interaction, { node: "http://localhost:8080" })
+const pingResult = await sdk.decode(response)
+console.log(`Ping result: ${pingResult.tag}`) // Should output: Ping result: PONG
 ```
 
 ### Script Usage
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
-const response = await sdk.send(await sdk.pipe(await sdk.build([
-  sdk.args([sdk.arg("Hello Flow!", types.String)]),
+import { t } from "@onflow/sdk"
+
+// Build the script interaction
+const builtInteraction = await sdk.build([
+  sdk.args([sdk.arg("Hello Flow!", t.String)]),
   sdk.script`
     pub fun main(msg: String): Int {
       log(msg)
       return 7
     }
   `,
-]), [
-  sdk.resolve([
-    sdk.resolveArguments,
-    sdk.resolveParams,
-  ]),
-]), { node: "http://localhost:8080" })
+])
+
+// Resolve the interaction with required resolvers
+const resolvedInteraction = await sdk.pipe(builtInteraction, [
+  sdk.resolveArguments,
+  sdk.resolveParams,
+])
+
+// Send the interaction to the Access Node
+const response = await sdk.send(resolvedInteraction, { node: "http://localhost:8080" })
+// Decode the response to get the result (a number in this case)
+const result: number = await sdk.decode(response)
+console.log(`Script returned: ${result}`) // Should output: Script returned: 7
 ```
 
 ### Transaction Usage
 
-```javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-import * as types from "@onflow/types"
-const response = await sdk.send(await sdk.pipe(await sdk.build([
+import { t } from "@onflow/sdk"
+
+// Define a signing function
+const signingFunction = () => ({ signature: "generated-signature" })
+
+// Build the transaction interaction with all required components
+const builtInteraction = await sdk.build([
   sdk.transaction`transaction(msg: String) { prepare(acct: AuthAccount) {} execute { log(msg) } }`,
-  sdk.args([sdk.arg("Hello, Flow!", types.String)]),
-  sdk.payer(sdk.authorization("01", signingFunction, 0)),
-  sdk.proposer(sdk.authorization("01", signingFunction, 0)),
-  sdk.authorizations([sdk.authorization("01", signingFunction, 0)]),
-  sdk.voucherIntercept(async voucher => {}), // Optional
-]), [
-  sdk.resolve([
-    sdk.resolveArguments,
-    sdk.resolveParams,
-    sdk.resolveAccounts,
-    sdk.resolveProposerSequenceNumber({ node: "http://localhost:8080" }),
-    sdk.resolveRefBlockId({ node: "http://localhost:8080" }),
-    sdk.resolveSignatures,
-    sdk.resolveVoucherIntercept, // Optional
-  ]),
-]), { node: "http://localhost:8080" })
+  sdk.args([sdk.arg("Hello, Flow!", t.String)]),
+  sdk.payer(sdk.authorization("0x01", signingFunction, 0)),
+  sdk.proposer(sdk.authorization("0x01", signingFunction, 0)),
+  sdk.authorizations([sdk.authorization("0x01", signingFunction, 0)]),
+  // Optional voucher intercept
+  sdk.voucherIntercept(async (voucher: any) => {
+    // Process the voucher before the transaction is sent
+    console.log("Processing voucher:", voucher)
+  }),
+])
+
+// Resolve the transaction with all required resolvers
+const resolvedInteraction = await sdk.pipe(builtInteraction, [
+  sdk.resolveArguments,
+  sdk.resolveParams,
+  sdk.resolveAccounts,
+  sdk.resolveProposerSequenceNumber({ node: "http://localhost:8080" }),
+  sdk.resolveRefBlockId({ node: "http://localhost:8080" }),
+  sdk.resolveSignatures,
+  // Optional resolver for voucher intercept
+  sdk.resolveVoucherIntercept,
+])
+
+// Send the transaction to the Access Node
+const response = await sdk.send(resolvedInteraction, { node: "http://localhost:8080" })
+
+// Decode the response to get the transaction ID
+const txId: string = await sdk.decode(response)
+console.log(`Transaction ID: ${txId}`)
 ```
 
 ### Get Network Parameters Usage
 
-``` javascript
+```typescript
 import * as sdk from "@onflow/sdk"
-const response = await sdk.send(await sdk.build([
+
+// Build the interaction to get network parameters
+const interaction = await sdk.build([
   sdk.getNetworkParameters()
-]), { node: "http://localhost:8080" })
+])
+
+// Send the interaction to the Access Node
+const response = await sdk.send(interaction, { node: "http://localhost:8080" })
+
+// Decode the response to get network parameters
+interface NetworkParameters {
+  chainId: string;
+}
+
+const params: NetworkParameters = await sdk.decode(response)
+console.log(`Chain ID: ${params.chainId}`)
 ```
 
 ## Flow JS-SDK Exposes
@@ -498,43 +624,43 @@ const response = await sdk.send(await sdk.build([
 - [Builders](./src/build)
 
   - [`sdk.args` & `sdk.arg`](./src/build/build-arguments.ts)
-  - [`sdk.atBlockHeight`](./src/build/build-at-block-height.js)
-  - [`sdk.atBlockId`](./src/build/build-at-block-id.js)
-  - [`sdk.authorizations` & `authorization`](./src/build/build-authorizations.js)
-  - [`sdk.getAccount`](./src/build/build-get-account.js)
-  - [`sdk.getBlock`](./src/build/build-get-block.js)
-  - [`sdk.getBlockByHeight`](./src/build/build-get-block-by-height)
-  - [`sdk.getBlockById`](./src/build/build-get-block-by-id.js)
-  - [`sdk.getBlockHeader`](./src/build/build-get-block-header.js)
-  - [`sdk.getCollection`](./src/build/build-get-collection)
-  - [`sdk.getEvents`](./src/build/build-get-events.js)
-  - [`sdk.getEventsAtBlockHeightRange`](./src/build/build-get-events-at-block-height-range.js)
-  - [`sdk.getEventsAtBlockIds`](./src/build/build-get-events-at-block-ids.js)
-  - [`sdk.getLatestBlock`](./src/build/build-get-latest-block.js)
-  - [`sdk.getTransactionStatus`](./src/build/build-get-transaction-status.js)
-  - [`sdk.getTransaction`](./src/build/build-get-transaction.js)
-  - [`sdk.getNetworkParameters`](./src/build/build-get-network-parameters.js)
-  - [`sdk.invariant`](./src/build/build-invariant.js)
-  - [`sdk.limit`](./src/build/build-limit.js)
-  - [`sdk.payer`](./src/build/build-payer.js)
-  - [`sdk.ping`](./src/build/build-ping.js)
-  - [`sdk.voucherIntercept`](./src/build/build-voucher-intercept.js)
-  - [`sdk.proposer`](./src/build/build-proposer.js)
-  - [`sdk.ref`](./src/build/build-ref.js)
-  - [`sdk.script`](./src/build/build-script.js)
-  - [`sdk.transaction`](./src/build/build-transaction.js)
-  - [`sdk.validator`](./src/build/build-validator.js)
+  - [`sdk.atBlockHeight`](./src/build/build-at-block-height.ts)
+  - [`sdk.atBlockId`](./src/build/build-at-block-id.ts)
+  - [`sdk.authorizations` & `authorization`](./src/build/build-authorizations.ts)
+  - [`sdk.getAccount`](./src/build/build-get-account.ts)
+  - [`sdk.getBlock`](./src/build/build-get-block.ts)
+  - [`sdk.getBlockByHeight`](./src/build/build-get-block-by-height.ts)
+  - [`sdk.getBlockById`](./src/build/build-get-block-by-id.ts)
+  - [`sdk.getBlockHeader`](./src/build/build-get-block-header.ts)
+  - [`sdk.getCollection`](./src/build/build-get-collection.ts)
+  - [`sdk.getEvents`](./src/build/build-get-events.ts)
+  - [`sdk.getEventsAtBlockHeightRange`](./src/build/build-get-events-at-block-height-range.ts)
+  - [`sdk.getEventsAtBlockIds`](./src/build/build-get-events-at-block-ids.ts)
+  - [`sdk.getLatestBlock`](./src/build/build-get-latest-block.ts)
+  - [`sdk.getTransactionStatus`](./src/build/build-get-transaction-status.ts)
+  - [`sdk.getTransaction`](./src/build/build-get-transaction.ts)
+  - [`sdk.getNetworkParameters`](./src/build/build-get-network-parameters.ts)
+  - [`sdk.invariant`](./src/build/build-invariant.ts)
+  - [`sdk.limit`](./src/build/build-limit.ts)
+  - [`sdk.payer`](./src/build/build-payer.ts)
+  - [`sdk.ping`](./src/build/build-ping.ts)
+  - [`sdk.voucherIntercept`](./src/build/build-voucher-intercept.ts)
+  - [`sdk.proposer`](./src/build/build-proposer.ts)
+  - [`sdk.ref`](./src/build/build-ref.ts)
+  - [`sdk.script`](./src/build/build-script.ts)
+  - [`sdk.transaction`](./src/build/build-transaction.ts)
+  - [`sdk.validator`](./src/build/build-validator.ts)
 
 - [Resolvers](./src/resolve)
   - [`sdk.resolveAccounts`](./src/resolve/resolve-accounts.ts)
-  - [`sdk.resolveArguments`](./src/resolve/resolve-arguments.js)
-  - [`sdk.resolveCadence`](./src/resolve/resolve-cadence.js)
-  - [`sdk.resolveFinalNormalization`](./src/resolve/resolve-final-normalization.js)
-  - [`sdk.resolveVoucherIntercept`](./src/resolve/resolve-voucher-intercept.js)
-  - [`sdk.resolveProposerSequenceNumber`](./src/resolve/resolve-proposer-sequence-number.js)
-  - [`sdk.resolveRefBlockId`](./src/resolve/resolve-ref-block-id.js)
+  - [`sdk.resolveArguments`](./src/resolve/resolve-arguments.ts)
+  - [`sdk.resolveCadence`](./src/resolve/resolve-cadence.ts)
+  - [`sdk.resolveFinalNormalization`](./src/resolve/resolve-final-normalization.ts)
+  - [`sdk.resolveVoucherIntercept`](./src/resolve/resolve-voucher-intercept.ts)
+  - [`sdk.resolveProposerSequenceNumber`](./src/resolve/resolve-proposer-sequence-number.ts)
+  - [`sdk.resolveRefBlockId`](./src/resolve/resolve-ref-block-id.ts)
   - [`sdk.resolveSignatures`](./src/resolve/resolve-signatures.ts)
-  - [`sdk.resolveValidators`](./src/resolve/resolve-validators.js)
+  - [`sdk.resolveValidators`](./src/resolve/resolve-validators.ts)
 
 - [Other Utils](./src/)
   - [`sdk.voucherToTxId`](./src/resolve/voucher.ts)
diff --git a/packages/sdk/src/VERSION.js b/packages/sdk/src/VERSION.js
deleted file mode 100644
index 5883643f..00000000
--- a/packages/sdk/src/VERSION.js
+++ /dev/null
@@ -1 +0,0 @@
-export const VERSION = PACKAGE_CURRENT_VERSION || "TESTVERSION"
diff --git a/packages/sdk/src/VERSION.ts b/packages/sdk/src/VERSION.ts
new file mode 100644
index 00000000..d9ff78b7
--- /dev/null
+++ b/packages/sdk/src/VERSION.ts
@@ -0,0 +1,3 @@
+declare const PACKAGE_CURRENT_VERSION: string | undefined
+
+export const VERSION: string = PACKAGE_CURRENT_VERSION || "TESTVERSION"
diff --git a/packages/sdk/src/account/account.ts b/packages/sdk/src/account/account.ts
index 8dec7266..e9bbf2d0 100644
--- a/packages/sdk/src/account/account.ts
+++ b/packages/sdk/src/account/account.ts
@@ -1,29 +1,31 @@
-import {atBlockHeight} from "../build/build-at-block-height.js"
-import {atBlockId} from "../build/build-at-block-id.js"
-import {atLatestBlock} from "../build/build-at-latest-block.js"
-import {getAccount} from "../build/build-get-account.js"
-import {invariant} from "@onflow/util-invariant"
-import {decodeResponse as decode} from "../decode/decode.js"
-import {send} from "../send/send.js"
 import type {Account} from "@onflow/typedefs"
+import {invariant} from "@onflow/util-invariant"
+import {atBlockHeight} from "../build/build-at-block-height"
+import {atBlockId} from "../build/build-at-block-id"
+import {atLatestBlock} from "../build/build-at-latest-block"
+import {getAccount} from "../build/build-get-account"
+import {decodeResponse as decode} from "../decode/decode"
+import {send} from "../send/send"
+
+interface AccountQueryOptions {
+  height?: number
+  id?: string
+  isSealed?: boolean
+}
 
 /**
  * @description Returns the details of an account from their public address
- * @param address - Address of the account
- * @param queryOptions - Query parameters
- * @param queryOptions.height - Block height to query
- * @param queryOptions.id - Block ID to query
- * @param queryOptions.isSealed - Block finality
- * @param opts - Optional parameters
+ * @param address Address of the account
+ * @param queryOptions Query parameters
+ * @param queryOptions.height Block height to query
+ * @param queryOptions.id Block ID to query
+ * @param queryOptions.isSealed Block finality
+ * @param opts Optional parameters
  * @returns A promise that resolves to an account response
  */
 export async function account(
   address: string,
-  {
-    height,
-    id,
-    isSealed,
-  }: {height?: number; id?: string; isSealed?: boolean} = {},
+  {height, id, isSealed}: AccountQueryOptions = {},
   opts?: object
 ): Promise<Account> {
   invariant(
@@ -32,18 +34,21 @@ export async function account(
   )
 
   // Get account by ID
-  if (id)
-    return await send([getAccount(address), atBlockId(id)], opts).then(decode)
+  if (id) {
+    const ix = await send([getAccount(address), atBlockId(id)], opts)
+    return decode(ix)
+  }
 
   // Get account by height
-  if (height)
-    return await send([getAccount(address), atBlockHeight(height)], opts).then(
-      decode
-    )
+  if (height) {
+    const ix = await send([getAccount(address), atBlockHeight(height)], opts)
+    return decode(ix)
+  }
 
   // Get account by latest block
-  return await send(
+  const ix = await send(
     [getAccount(address), atLatestBlock(isSealed ?? false)],
     opts
-  ).then(decode)
+  )
+  return decode(ix)
 }
diff --git a/packages/sdk/src/block/block.js b/packages/sdk/src/block/block.js
deleted file mode 100644
index 6cc92df8..00000000
--- a/packages/sdk/src/block/block.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import {send} from "../send/send.js"
-import {getBlock} from "../build/build-get-block"
-import {atBlockHeight} from "../build/build-at-block-height.js"
-import {atBlockId} from "../build/build-at-block-id.js"
-import {decodeResponse as decode} from "../decode/decode.js"
-import {invariant} from "@onflow/util-invariant"
-
-/**
- * @typedef {import("@onflow/typedefs").Block} Block
- */
-
-/**
- * @description Returns the latest block (optionally sealed or not), by id, or by height
- * @param {object} [queryOptions] - Query parameters
- * @param {boolean} [queryOptions.sealed] - Whether to query for a sealed block
- * @param {number} [queryOptions.height] - Block height to query
- * @param {string} [queryOptions.id] - Block ID to query
- * @param {object} [opts] - Optional parameters
- * @returns {Promise<Block>} - A promise that resolves to a block response
- */
-export function block({sealed = false, id, height} = {}, opts = {}) {
-  invariant(
-    !((sealed && id) || (sealed && height)),
-    `Method: block -- Cannot pass "sealed" with "id" or "height"`
-  )
-
-  invariant(
-    !(id && height),
-    `Method: block -- Cannot pass "id" and "height" simultaneously`
-  )
-
-  // Get block by ID
-  if (id) return send([getBlock(), atBlockId(id)], opts).then(decode)
-
-  // Get block by height
-  if (height)
-    return send([getBlock(), atBlockHeight(height)], opts).then(decode)
-
-  // Get latest block
-  return send([getBlock(sealed)], opts).then(decode)
-}
diff --git a/packages/sdk/src/block/block.ts b/packages/sdk/src/block/block.ts
new file mode 100644
index 00000000..d68676c0
--- /dev/null
+++ b/packages/sdk/src/block/block.ts
@@ -0,0 +1,53 @@
+import type {Block} from "@onflow/typedefs"
+import {invariant} from "@onflow/util-invariant"
+import {atBlockHeight} from "../build/build-at-block-height"
+import {atBlockId} from "../build/build-at-block-id"
+import {getBlock} from "../build/build-get-block"
+import {decodeResponse as decode} from "../decode/decode"
+import {send} from "../send/send"
+
+interface BlockQueryOptions {
+  sealed?: boolean
+  height?: number
+  id?: string
+}
+
+/**
+ * @description Returns the latest block (optionally sealed or not), by id, or by height
+ * @param queryOptions Query parameters
+ * @param queryOptions.sealed Whether to query for a sealed block
+ * @param queryOptions.height Block height to query
+ * @param queryOptions.id Block ID to query
+ * @param opts Optional parameters
+ * @returns A promise that resolves to a block response
+ */
+export async function block(
+  {sealed = false, id, height}: BlockQueryOptions = {},
+  opts: object = {}
+): Promise<Block> {
+  invariant(
+    !((sealed && id) || (sealed && height)),
+    `Method: block -- Cannot pass "sealed" with "id" or "height"`
+  )
+
+  invariant(
+    !(id && height),
+    `Method: block -- Cannot pass "id" and "height" simultaneously`
+  )
+
+  // Get block by ID
+  if (id) {
+    const ix = await send([getBlock(), atBlockId(id)], opts)
+    return decode(ix)
+  }
+
+  // Get block by height
+  if (height) {
+    const ix = await send([getBlock(), atBlockHeight(height)], opts)
+    return decode(ix)
+  }
+
+  // Get latest block
+  const ix = await send([getBlock(sealed)], opts)
+  return decode(ix)
+}
diff --git a/packages/sdk/src/build/build-at-block-height.js b/packages/sdk/src/build/build-at-block-height.js
deleted file mode 100644
index 1a295287..00000000
--- a/packages/sdk/src/build/build-at-block-height.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import {pipe} from "../interaction/interaction"
-import {validator} from "./build-validator.js"
-
-/**
- * @description - A builder function that returns a partial interaction to a block at a specific height
- * @param {number} height - The height of the block to get
- * @returns {Function} - A partial interaction object
- */
-export function atBlockHeight(height) {
-  return pipe([
-    ix => {
-      ix.block.height = height
-      return ix
-    },
-    validator(ix => {
-      if (typeof ix.block.isSealed === "boolean")
-        throw new Error("Unable to specify both block height and isSealed.")
-      if (ix.block.id)
-        throw new Error("Unable to specify both block height and block id.")
-      return ix
-    }),
-  ])
-}
diff --git a/packages/sdk/src/build/build-at-block-height.ts b/packages/sdk/src/build/build-at-block-height.ts
new file mode 100644
index 00000000..d0485668
--- /dev/null
+++ b/packages/sdk/src/build/build-at-block-height.ts
@@ -0,0 +1,24 @@
+import {pipe, InteractionBuilderFn} from "../interaction/interaction"
+import {Interaction} from "@onflow/typedefs"
+import {validator} from "./build-validator"
+
+/**
+ * @description A builder function that returns a partial interaction to a block at a specific height
+ * @param height The height of the block to get
+ * @returns A function that processes a partial interaction object
+ */
+export function atBlockHeight(height: number): InteractionBuilderFn {
+  return pipe([
+    (ix: Interaction) => {
+      ix.block.height = height
+      return ix
+    },
+    validator((ix: Interaction) => {
+      if (typeof ix.block.isSealed === "boolean")
+        throw new Error("Unable to specify both block height and isSealed.")
+      if (ix.block.id)
+        throw new Error("Unable to specify both block height and block id.")
+      return ix
+    }),
+  ])
+}
diff --git a/packages/sdk/src/build/build-at-block-id.js b/packages/sdk/src/build/build-at-block-id.js
deleted file mode 100644
index 581568d0..00000000
--- a/packages/sdk/src/build/build-at-block-id.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import {isGetAccount, pipe, Ok} from "../interaction/interaction"
-import {validator} from "./build-validator.js"
-
-export function atBlockId(id) {
-  return pipe([
-    ix => {
-      ix.block.id = id
-      return Ok(ix)
-    },
-    validator((ix, {Ok, Bad}) => {
-      if (isGetAccount(ix))
-        return Bad(
-          ix,
-          "Unable to specify a block id with a Get Account interaction."
-        )
-      if (typeof ix.block.isSealed === "boolean")
-        return Bad(ix, "Unable to specify both block id and isSealed.")
-      if (ix.block.height)
-        return Bad(ix, "Unable to specify both block id and block height.")
-      return Ok(ix)
-    }),
-  ])
-}
diff --git a/packages/sdk/src/build/build-at-block-id.ts b/packages/sdk/src/build/build-at-block-id.ts
new file mode 100644
index 00000000..7d7ea30f
--- /dev/null
+++ b/packages/sdk/src/build/build-at-block-id.ts
@@ -0,0 +1,32 @@
+import {
+  isGetAccount,
+  pipe,
+  Ok as OkFn,
+  Bad as BadFn,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+import {validator} from "./build-validator"
+import {Interaction} from "@onflow/typedefs"
+
+export function atBlockId(id: string): InteractionBuilderFn {
+  return pipe([
+    (ix: Interaction) => {
+      ix.block.id = id
+      return OkFn(ix)
+    },
+    validator(
+      (ix: Interaction, {Ok, Bad}: {Ok: typeof OkFn; Bad: typeof BadFn}) => {
+        if (isGetAccount(ix))
+          return Bad(
+            ix,
+            "Unable to specify a block id with a Get Account interaction."
+          )
+        if (typeof ix.block.isSealed === "boolean")
+          return Bad(ix, "Unable to specify both block id and isSealed.")
+        if (ix.block.height)
+          return Bad(ix, "Unable to specify both block id and block height.")
+        return Ok(ix)
+      }
+    ),
+  ])
+}
diff --git a/packages/sdk/src/build/build-at-latest-block.js b/packages/sdk/src/build/build-at-latest-block.js
deleted file mode 100644
index 038bf995..00000000
--- a/packages/sdk/src/build/build-at-latest-block.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import {pipe} from "../interaction/interaction"
-import {validator} from "./build-validator"
-
-/**
- * @description - A builder function that returns a partial interaction to query the latest block with the given finality state
- * @param {boolean} [isSealed=false] - Block finality state, defaults to latest executed block ("soft-finality"), set to true for sealed blocks ("hard-finality")
- * @returns {Function} - A partial interaction object
- */
-export function atLatestBlock(isSealed = false) {
-  return pipe([
-    ix => {
-      ix.block.isSealed = isSealed
-      return ix
-    },
-    validator(ix => {
-      if (ix.block.id)
-        throw new Error("Unable to specify both block finality and block id.")
-      if (ix.block.height)
-        throw new Error(
-          "Unable to specify both block finality and block height."
-        )
-      return ix
-    }),
-  ])
-}
diff --git a/packages/sdk/src/build/build-at-latest-block.ts b/packages/sdk/src/build/build-at-latest-block.ts
new file mode 100644
index 00000000..115e5fe1
--- /dev/null
+++ b/packages/sdk/src/build/build-at-latest-block.ts
@@ -0,0 +1,26 @@
+import {pipe, InteractionBuilderFn} from "../interaction/interaction"
+import {Interaction} from "@onflow/typedefs"
+import {validator} from "./build-validator"
+
+/**
+ * @description A builder function that returns a partial interaction to query the latest block with the given finality state
+ * @param isSealed Block finality state, defaults to latest executed block ("soft-finality"), set to true for sealed blocks ("hard-finality")
+ * @returns A function that processes a partial interaction object
+ */
+export function atLatestBlock(isSealed = false): InteractionBuilderFn {
+  return pipe([
+    (ix: Interaction) => {
+      ix.block.isSealed = isSealed
+      return ix
+    },
+    validator((ix: Interaction) => {
+      if (ix.block.id)
+        throw new Error("Unable to specify both block finality and block id.")
+      if (ix.block.height)
+        throw new Error(
+          "Unable to specify both block finality and block height."
+        )
+      return ix
+    }),
+  ])
+}
diff --git a/packages/sdk/src/build/build-authorizations.js b/packages/sdk/src/build/build-authorizations.js
deleted file mode 100644
index 64a5b4b6..00000000
--- a/packages/sdk/src/build/build-authorizations.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import {TransactionRole} from "@onflow/typedefs"
-import {pipe, prepAccount} from "../interaction/interaction"
-
-export function authorizations(ax = []) {
-  return pipe(
-    ax.map(authz => {
-      return prepAccount(authz, {role: TransactionRole.AUTHORIZER})
-    })
-  )
-}
-
-export function authorization(addr, signingFunction, keyId, sequenceNum) {
-  return {addr, signingFunction, keyId, sequenceNum}
-}
diff --git a/packages/sdk/src/build/build-authorizations.ts b/packages/sdk/src/build/build-authorizations.ts
new file mode 100644
index 00000000..28c249e8
--- /dev/null
+++ b/packages/sdk/src/build/build-authorizations.ts
@@ -0,0 +1,48 @@
+import {InteractionAccount, TransactionRole} from "@onflow/typedefs"
+import {
+  AccountAuthorization,
+  pipe,
+  prepAccount,
+} from "../interaction/interaction"
+import {Voucher} from "../encode/encode"
+
+interface SignableMessage {
+  message: string
+  addr: string
+  keyId: number | string
+  roles: {
+    proposer: boolean
+    authorizer: boolean
+    payer: boolean
+  }
+  voucher: Voucher
+}
+
+interface SigningResult {
+  addr?: string
+  keyId?: number | string
+  signature: string
+}
+
+type SigningFn = (
+  signable?: SignableMessage
+) => SigningResult | Promise<SigningResult>
+
+export function authorizations(ax: Array<AccountAuthorization> = []) {
+  return pipe(
+    ax.map(authz => {
+      return prepAccount(authz, {
+        role: TransactionRole.AUTHORIZER,
+      })
+    })
+  )
+}
+
+export function authorization(
+  addr: string,
+  signingFunction: SigningFn,
+  keyId?: number | string,
+  sequenceNum?: number
+): Partial<InteractionAccount> {
+  return {addr, signingFunction, keyId, sequenceNum}
+}
diff --git a/packages/sdk/src/build/build-get-account.js b/packages/sdk/src/build/build-get-account.js
deleted file mode 100644
index b25adf31..00000000
--- a/packages/sdk/src/build/build-get-account.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import {pipe, makeGetAccount, Ok} from "../interaction/interaction"
-import {sansPrefix} from "@onflow/util-address"
-
-/**
- * @description - A builder function that returns the interaction to get an account by address
- * @param {string} addr - The address of the account to getq
- * @returns {Function} - An interaction object
- */
-export function getAccount(addr) {
-  return pipe([
-    makeGetAccount,
-    ix => {
-      ix.account.addr = sansPrefix(addr)
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-account.ts b/packages/sdk/src/build/build-get-account.ts
new file mode 100644
index 00000000..c45086db
--- /dev/null
+++ b/packages/sdk/src/build/build-get-account.ts
@@ -0,0 +1,22 @@
+import {sansPrefix} from "@onflow/util-address"
+import {
+  InteractionBuilderFn,
+  makeGetAccount,
+  Ok,
+  pipe,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get an account by address
+ * @param addr The address of the account to get
+ * @returns A function that processes an interaction object
+ */
+export function getAccount(addr: string): InteractionBuilderFn {
+  return pipe([
+    makeGetAccount,
+    ix => {
+      ix.account.addr = sansPrefix(addr)
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-block-header.js b/packages/sdk/src/build/build-get-block-header.js
deleted file mode 100644
index b803793a..00000000
--- a/packages/sdk/src/build/build-get-block-header.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import {pipe, Ok, makeGetBlockHeader} from "../interaction/interaction"
-
-/**
- * @description - A builder function that returns the interaction to get a block header
- * @param {boolean} [isSealed] - Whether or not the block should be sealed
- * @returns {Function} - An interaction object
- */
-export function getBlockHeader(isSealed = null) {
-  return pipe([
-    makeGetBlockHeader,
-    ix => {
-      ix.block.isSealed = isSealed
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-block-header.ts b/packages/sdk/src/build/build-get-block-header.ts
new file mode 100644
index 00000000..7144a181
--- /dev/null
+++ b/packages/sdk/src/build/build-get-block-header.ts
@@ -0,0 +1,23 @@
+import {
+  pipe,
+  Ok,
+  makeGetBlockHeader,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get a block header
+ * @param isSealed Whether or not the block should be sealed
+ * @returns A function that processes an interaction object
+ */
+export function getBlockHeader(
+  isSealed: boolean | null = null
+): InteractionBuilderFn {
+  return pipe([
+    makeGetBlockHeader,
+    ix => {
+      ix.block.isSealed = isSealed
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-block.js b/packages/sdk/src/build/build-get-block.js
deleted file mode 100644
index 0f8604c7..00000000
--- a/packages/sdk/src/build/build-get-block.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import {pipe, Ok, makeGetBlock} from "../interaction/interaction"
-
-/**
- * @description - A builder function that returns the interaction to get the latest block
- * @param {boolean} [isSealed] - Whether or not the block should be sealed
- * @returns {Function} - An interaction object
- */
-export function getBlock(isSealed = null) {
-  return pipe([
-    makeGetBlock,
-    ix => {
-      ix.block.isSealed = isSealed
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-block.ts b/packages/sdk/src/build/build-get-block.ts
new file mode 100644
index 00000000..bcf9fda6
--- /dev/null
+++ b/packages/sdk/src/build/build-get-block.ts
@@ -0,0 +1,23 @@
+import {
+  pipe,
+  Ok,
+  makeGetBlock,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get the latest block
+ * @param isSealed Whether or not the block should be sealed
+ * @returns A function that processes an interaction object
+ */
+export function getBlock(
+  isSealed: boolean | null = null
+): InteractionBuilderFn {
+  return pipe([
+    makeGetBlock,
+    ix => {
+      ix.block.isSealed = isSealed
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-collection.js b/packages/sdk/src/build/build-get-collection.js
deleted file mode 100644
index 96f0ca58..00000000
--- a/packages/sdk/src/build/build-get-collection.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import {pipe, makeGetCollection} from "../interaction/interaction"
-
-/**
- * @description - A builder function that returns all a collection containing a list of transaction ids by its collection id
- * NOTE:
- * - The block range provided must be from the current spork. All events emitted during past sporks is current unavailable.
- * @param {string} [id] - The id of the collection to get
- * @returns {Function} - An interaction object
- */
-export function getCollection(id = null) {
-  return pipe([
-    makeGetCollection,
-    ix => {
-      ix.collection.id = id
-      return ix
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-collection.ts b/packages/sdk/src/build/build-get-collection.ts
new file mode 100644
index 00000000..b5397f0e
--- /dev/null
+++ b/packages/sdk/src/build/build-get-collection.ts
@@ -0,0 +1,21 @@
+import {
+  pipe,
+  Ok,
+  makeGetCollection,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get a collection by ID
+ * @param id The ID of the collection to get
+ * @returns A function that processes an interaction object
+ */
+export function getCollection(id: string | null = null): InteractionBuilderFn {
+  return pipe([
+    makeGetCollection,
+    ix => {
+      ix.collection.id = id
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-events-at-block-height-range.js b/packages/sdk/src/build/build-get-events-at-block-height-range.js
deleted file mode 100644
index 569aa12e..00000000
--- a/packages/sdk/src/build/build-get-events-at-block-height-range.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import {pipe, Ok, makeGetEvents} from "../interaction/interaction"
-
-/**
- * @description - A builder function that returns all instances of a particular event (by name) within a height range
- * NOTE:
- * - The block range provided must be from the current spork.
- * - The block range provided must be 250 blocks or lower per request.
- * @param {string} eventName - The name of the event to get
- * @param {number} fromBlockHeight - The height of the block to start looking for events (inclusive)
- * @param {number} toBlockHeight - The height of the block to stop looking for events (inclusive)
- * @returns {Function} - An interaction object
- */
-export function getEventsAtBlockHeightRange(
-  eventName,
-  fromBlockHeight,
-  toBlockHeight
-) {
-  return pipe([
-    makeGetEvents,
-    ix => {
-      ix.events.eventType = eventName
-      ix.events.start = fromBlockHeight
-      ix.events.end = toBlockHeight
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-events-at-block-height-range.ts b/packages/sdk/src/build/build-get-events-at-block-height-range.ts
new file mode 100644
index 00000000..85a01959
--- /dev/null
+++ b/packages/sdk/src/build/build-get-events-at-block-height-range.ts
@@ -0,0 +1,29 @@
+import {
+  pipe,
+  Ok,
+  makeGetEvents,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get events at a block height range
+ * @param eventType The type of event to get
+ * @param startHeight The start height of the block range
+ * @param endHeight The end height of the block range
+ * @returns A function that processes an interaction object
+ */
+export function getEventsAtBlockHeightRange(
+  eventType: string,
+  startHeight: number,
+  endHeight: number
+): InteractionBuilderFn {
+  return pipe([
+    makeGetEvents,
+    ix => {
+      ix.events.eventType = eventType
+      ix.events.start = startHeight
+      ix.events.end = endHeight
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-events-at-block-ids.js b/packages/sdk/src/build/build-get-events-at-block-ids.js
deleted file mode 100644
index 6fe53403..00000000
--- a/packages/sdk/src/build/build-get-events-at-block-ids.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import {pipe, Ok, makeGetEvents} from "../interaction/interaction"
-
-/**
- * @description - A builder function that returns all instances of a particular event (by name) within a set of blocks, specified by block ids
- * NOTE:
- * - The block range provided must be from the current spork.
- * @param {string} eventName - The name of the event to get
- * @param {number[]} blockIds - The ids of the blocks to look for events
- * @returns {Function} - An interaction object
- */
-export function getEventsAtBlockIds(eventName, blockIds = []) {
-  return pipe([
-    makeGetEvents,
-    ix => {
-      ix.events.eventType = eventName
-      ix.events.blockIds = blockIds
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-events-at-block-ids.ts b/packages/sdk/src/build/build-get-events-at-block-ids.ts
new file mode 100644
index 00000000..1b2bc02d
--- /dev/null
+++ b/packages/sdk/src/build/build-get-events-at-block-ids.ts
@@ -0,0 +1,26 @@
+import {
+  pipe,
+  Ok,
+  makeGetEvents,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get events at specific block IDs
+ * @param eventType The type of event to get
+ * @param blockIds The block IDs to get events from
+ * @returns A function that processes an interaction object
+ */
+export function getEventsAtBlockIds(
+  eventType: string,
+  blockIds: string[]
+): InteractionBuilderFn {
+  return pipe([
+    makeGetEvents,
+    ix => {
+      ix.events.eventType = eventType
+      ix.events.blockIds = blockIds
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-events.js b/packages/sdk/src/build/build-get-events.js
deleted file mode 100644
index f338524e..00000000
--- a/packages/sdk/src/build/build-get-events.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import {pipe, Ok, makeGetEvents} from "../interaction/interaction"
-import * as logger from "@onflow/util-logger"
-
-export function getEvents(eventType, start, end) {
-  if (typeof start !== "undefined" || typeof end !== "undefined") {
-    logger.log.deprecate({
-      pkg: "FCL/SDK",
-      subject: "Passing a start and end into getEvents",
-      transition:
-        "https://github.com/onflow/flow-js-sdk/blob/master/packages/sdk/TRANSITIONS.md#0005-deprecate-start-end-get-events-builder",
-    })
-  }
-
-  return pipe([
-    makeGetEvents,
-    ix => {
-      ix.events.eventType = eventType
-      ix.events.start = start
-      ix.events.end = end
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-events.ts b/packages/sdk/src/build/build-get-events.ts
new file mode 100644
index 00000000..c70f16d4
--- /dev/null
+++ b/packages/sdk/src/build/build-get-events.ts
@@ -0,0 +1,29 @@
+import {
+  pipe,
+  Ok,
+  makeGetEvents,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get events
+ * @param eventType The type of event to get
+ * @param start The start block ID or height
+ * @param end The end block ID or height
+ * @returns A function that processes an interaction object
+ */
+export function getEvents(
+  eventType: string,
+  start: number,
+  end: number
+): InteractionBuilderFn {
+  return pipe([
+    makeGetEvents,
+    ix => {
+      ix.events.eventType = eventType
+      ix.events.start = start
+      ix.events.end = end
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-latest-block.js b/packages/sdk/src/build/build-get-latest-block.js
deleted file mode 100644
index 005a7355..00000000
--- a/packages/sdk/src/build/build-get-latest-block.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import {log} from "@onflow/util-logger"
-import {pipe, Ok, makeGetLatestBlock} from "../interaction/interaction"
-
-export function getLatestBlock(isSealed = false) {
-  log.deprecate({
-    pkg: "FCL/SDK",
-    subject: "The getLatestBlock builder",
-    transition:
-      "https://github.com/onflow/flow-js-sdk/blob/master/packages/sdk/TRANSITIONS.md#0006-deprecate-get-latest-block-builder",
-  })
-
-  return pipe([
-    makeGetLatestBlock,
-    ix => {
-      ix.block.isSealed = isSealed
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-latest-block.ts b/packages/sdk/src/build/build-get-latest-block.ts
new file mode 100644
index 00000000..7414cc1e
--- /dev/null
+++ b/packages/sdk/src/build/build-get-latest-block.ts
@@ -0,0 +1,31 @@
+import {log} from "@onflow/util-logger"
+import {
+  pipe,
+  Ok,
+  makeGetBlock,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get the latest block
+ * @param isSealed Whether or not the block should be sealed
+ * @returns A function that processes an interaction object
+ */
+export function getLatestBlock(
+  isSealed: boolean = false
+): InteractionBuilderFn {
+  log.deprecate({
+    pkg: "FCL/SDK",
+    subject: "The getLatestBlock builder",
+    transition:
+      "https://github.com/onflow/flow-js-sdk/blob/master/packages/sdk/TRANSITIONS.md#0006-deprecate-get-latest-block-builder",
+  })
+
+  return pipe([
+    makeGetBlock,
+    ix => {
+      ix.block.isSealed = isSealed
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-network-parameters.js b/packages/sdk/src/build/build-get-network-parameters.js
deleted file mode 100644
index 760ba7a9..00000000
--- a/packages/sdk/src/build/build-get-network-parameters.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import {pipe, Ok, makeGetNetworkParameters} from "../interaction/interaction"
-
-export function getNetworkParameters() {
-  return pipe([
-    makeGetNetworkParameters,
-    ix => {
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-network-parameters.ts b/packages/sdk/src/build/build-get-network-parameters.ts
new file mode 100644
index 00000000..38dc7499
--- /dev/null
+++ b/packages/sdk/src/build/build-get-network-parameters.ts
@@ -0,0 +1,19 @@
+import {
+  pipe,
+  makeGetNetworkParameters,
+  Ok,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get network parameters
+ * @returns A function that processes an interaction object
+ */
+export function getNetworkParameters(): InteractionBuilderFn {
+  return pipe([
+    makeGetNetworkParameters,
+    ix => {
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-node-version-info.ts b/packages/sdk/src/build/build-get-node-version-info.ts
index 059fe407..e9c8aed4 100644
--- a/packages/sdk/src/build/build-get-node-version-info.ts
+++ b/packages/sdk/src/build/build-get-node-version-info.ts
@@ -1,9 +1,15 @@
-import {Ok, makeGetNodeVerionInfo, pipe} from "../interaction/interaction"
+import {
+  Ok,
+  makeGetNodeVerionInfo,
+  pipe,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
 
 /**
- * A builder function for the Get Node Version Info interaction
+ * @description A builder function for the Get Node Version Info interaction
+ * @returns An interaction object
  */
-export function getNodeVersionInfo(): Function {
+export function getNodeVersionInfo(): InteractionBuilderFn {
   return pipe([
     makeGetNodeVerionInfo,
     ix => {
diff --git a/packages/sdk/src/build/build-get-transaction-status.js b/packages/sdk/src/build/build-get-transaction-status.js
deleted file mode 100644
index adb4b680..00000000
--- a/packages/sdk/src/build/build-get-transaction-status.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import {pipe, Ok, makeGetTransactionStatus} from "../interaction/interaction"
-
-/**
- * @description - A builder function that returns the status of transaction
- * NOTE: The transactionID provided must be from the current spork.
- * @param {string} transactionId - The id of the transaction to get status
- * @returns {Function} - An interaction object
- */
-export function getTransactionStatus(transactionId) {
-  return pipe([
-    makeGetTransactionStatus,
-    ix => {
-      ix.transaction.id = transactionId
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-transaction-status.ts b/packages/sdk/src/build/build-get-transaction-status.ts
new file mode 100644
index 00000000..55585414
--- /dev/null
+++ b/packages/sdk/src/build/build-get-transaction-status.ts
@@ -0,0 +1,24 @@
+import {
+  pipe,
+  Ok,
+  makeGetTransactionStatus,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the status of transaction
+ * NOTE: The transactionID provided must be from the current spork.
+ * @param transactionId The id of the transaction to get status
+ * @returns An interaction object
+ */
+export function getTransactionStatus(
+  transactionId: string
+): InteractionBuilderFn {
+  return pipe([
+    makeGetTransactionStatus,
+    ix => {
+      ix.transaction.id = transactionId
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-get-transaction.js b/packages/sdk/src/build/build-get-transaction.js
deleted file mode 100644
index 4f559843..00000000
--- a/packages/sdk/src/build/build-get-transaction.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import {pipe, Ok, makeGetTransaction} from "../interaction/interaction"
-
-/**
- * @description - A builder function that returns a transaction
- * NOTE: The transactionID provided must be from the current spork.
- * @param {string} transactionId - The id of the transaction to get
- * @returns {Function} - An interaction object
- */
-export function getTransaction(transactionId) {
-  return pipe([
-    makeGetTransaction,
-    ix => {
-      ix.transaction.id = transactionId
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-get-transaction.ts b/packages/sdk/src/build/build-get-transaction.ts
new file mode 100644
index 00000000..f467ee23
--- /dev/null
+++ b/packages/sdk/src/build/build-get-transaction.ts
@@ -0,0 +1,21 @@
+import {
+  InteractionBuilderFn,
+  Ok,
+  makeGetTransaction,
+  pipe,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that returns the interaction to get a transaction by ID
+ * @param id The ID of the transaction to get
+ * @returns A function that processes an interaction object
+ */
+export function getTransaction(id: string): InteractionBuilderFn {
+  return pipe([
+    makeGetTransaction,
+    ix => {
+      ix.transaction.id = id
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-limit.js b/packages/sdk/src/build/build-limit.js
deleted file mode 100644
index e13f0cce..00000000
--- a/packages/sdk/src/build/build-limit.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export function limit(computeLimit) {
-  return ix => {
-    ix.message.computeLimit = computeLimit
-    return ix
-  }
-}
diff --git a/packages/sdk/src/build/build-limit.ts b/packages/sdk/src/build/build-limit.ts
new file mode 100644
index 00000000..7c9fa557
--- /dev/null
+++ b/packages/sdk/src/build/build-limit.ts
@@ -0,0 +1,13 @@
+import {InteractionBuilderFn} from "../interaction/interaction"
+
+/**
+ * @description A builder function that sets the compute limit for a transaction
+ * @param limit The compute limit to set
+ * @returns A function that processes an interaction object
+ */
+export function limit(limit: number): InteractionBuilderFn {
+  return ix => {
+    ix.message.computeLimit = limit
+    return ix
+  }
+}
diff --git a/packages/sdk/src/build/build-payer.js b/packages/sdk/src/build/build-payer.js
deleted file mode 100644
index 0828b7ad..00000000
--- a/packages/sdk/src/build/build-payer.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import {TransactionRole} from "@onflow/typedefs"
-import {pipe, prepAccount} from "../interaction/interaction"
-
-/**
- * @description - A builder function that adds payer account(s) to a transaction
- * @param {Function | Function[] | Object | Object[]} ax - An account address or array of account addresses
- * @returns {Function} - An interaction object
- */
-export function payer(ax = []) {
-  if (!Array.isArray(ax)) ax = [ax]
-  return pipe(
-    ax.map(authz => {
-      return prepAccount(authz, {role: TransactionRole.PAYER})
-    })
-  )
-}
diff --git a/packages/sdk/src/build/build-payer.ts b/packages/sdk/src/build/build-payer.ts
new file mode 100644
index 00000000..7380bd2c
--- /dev/null
+++ b/packages/sdk/src/build/build-payer.ts
@@ -0,0 +1,22 @@
+import {TransactionRole} from "@onflow/typedefs"
+import {
+  AccountAuthorization,
+  pipe,
+  prepAccount,
+} from "../interaction/interaction"
+
+/**
+ * @description A builder function that adds payer account(s) to a transaction
+ * @param ax An account address or array of account addresses
+ * @returns A function that takes an interaction and returns a new interaction with the payer(s) added
+ */
+export function payer(ax: AccountAuthorization[] = []) {
+  if (!Array.isArray(ax)) ax = [ax]
+  return pipe(
+    ax.map(authz => {
+      return prepAccount(authz, {
+        role: TransactionRole.PAYER,
+      })
+    })
+  )
+}
diff --git a/packages/sdk/src/build/build-ping.js b/packages/sdk/src/build/build-ping.js
deleted file mode 100644
index 0379ff2c..00000000
--- a/packages/sdk/src/build/build-ping.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import {makePing} from "../interaction/interaction"
-
-export function ping() {
-  return makePing
-}
diff --git a/packages/sdk/src/build/build-ping.ts b/packages/sdk/src/build/build-ping.ts
new file mode 100644
index 00000000..635227a7
--- /dev/null
+++ b/packages/sdk/src/build/build-ping.ts
@@ -0,0 +1,9 @@
+import {makePing, InteractionBuilderFn} from "../interaction/interaction"
+
+/**
+ * @description A builder function that creates a ping interaction
+ * @returns A function that processes an interaction object
+ */
+export function ping(): InteractionBuilderFn {
+  return makePing
+}
diff --git a/packages/sdk/src/build/build-proposer.js b/packages/sdk/src/build/build-proposer.js
deleted file mode 100644
index cef04872..00000000
--- a/packages/sdk/src/build/build-proposer.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import {TransactionRole} from "@onflow/typedefs"
-import {prepAccount} from "../interaction/interaction"
-
-export function proposer(authz) {
-  return prepAccount(authz, {role: TransactionRole.PROPOSER})
-}
diff --git a/packages/sdk/src/build/build-proposer.ts b/packages/sdk/src/build/build-proposer.ts
new file mode 100644
index 00000000..09230279
--- /dev/null
+++ b/packages/sdk/src/build/build-proposer.ts
@@ -0,0 +1,8 @@
+import {TransactionRole} from "@onflow/typedefs"
+import {AccountAuthorization, prepAccount} from "../interaction/interaction"
+
+export function proposer(authz: AccountAuthorization) {
+  return prepAccount(authz, {
+    role: TransactionRole.PROPOSER,
+  })
+}
diff --git a/packages/sdk/src/build/build-ref.js b/packages/sdk/src/build/build-ref.js
deleted file mode 100644
index bc164871..00000000
--- a/packages/sdk/src/build/build-ref.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import {pipe, Ok} from "../interaction/interaction"
-
-export function ref(refBlock) {
-  return pipe([
-    ix => {
-      ix.message.refBlock = refBlock
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-ref.ts b/packages/sdk/src/build/build-ref.ts
new file mode 100644
index 00000000..bca557da
--- /dev/null
+++ b/packages/sdk/src/build/build-ref.ts
@@ -0,0 +1,15 @@
+import {pipe, Ok, InteractionBuilderFn} from "../interaction/interaction"
+
+/**
+ * @description A builder function that sets the reference block for a transaction
+ * @param refBlock The reference block ID
+ * @returns A function that processes an interaction object
+ */
+export function ref(refBlock: string): InteractionBuilderFn {
+  return pipe([
+    ix => {
+      ix.message.refBlock = refBlock
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-script.js b/packages/sdk/src/build/build-script.js
deleted file mode 100644
index 9dbd8072..00000000
--- a/packages/sdk/src/build/build-script.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import {pipe, Ok, put, makeScript} from "../interaction/interaction"
-import {template} from "@onflow/util-template"
-
-export function script(...args) {
-  return pipe([makeScript, put("ix.cadence", template(...args))])
-}
diff --git a/packages/sdk/src/build/build-script.ts b/packages/sdk/src/build/build-script.ts
new file mode 100644
index 00000000..d51c73c6
--- /dev/null
+++ b/packages/sdk/src/build/build-script.ts
@@ -0,0 +1,20 @@
+import {
+  pipe,
+  put,
+  makeScript,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+import {template} from "@onflow/util-template"
+
+/**
+ * @description A builder function that creates a script interaction
+ * @returns A function that processes an interaction object
+ */
+export function script(
+  ...args: [
+    string | TemplateStringsArray | ((x?: unknown) => string),
+    ...unknown[],
+  ]
+): InteractionBuilderFn {
+  return pipe([makeScript, put("ix.cadence", template(...args))])
+}
diff --git a/packages/sdk/src/build/build-subscribe-events.ts b/packages/sdk/src/build/build-subscribe-events.ts
index b18fe9c4..a4648aef 100644
--- a/packages/sdk/src/build/build-subscribe-events.ts
+++ b/packages/sdk/src/build/build-subscribe-events.ts
@@ -1,9 +1,16 @@
 import {invariant} from "@onflow/util-invariant"
-import {pipe, Ok, makeSubscribeEvents} from "../interaction/interaction"
+import {
+  pipe,
+  Ok,
+  makeSubscribeEvents,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
 import {EventFilter, Interaction} from "@onflow/typedefs"
 
 /**
- * Subscribe to events with the given filter & parameters
+ * @description Subscribe to events with the given filter & parameters
+ * @param filter The filter to subscribe to events with
+ * @returns A function that processes an interaction object
  */
 export function subscribeEvents({
   startBlockId,
@@ -12,7 +19,7 @@ export function subscribeEvents({
   addresses,
   contracts,
   heartbeatInterval,
-}: EventFilter): Function {
+}: EventFilter): InteractionBuilderFn {
   invariant(
     !(startBlockId && startHeight),
     `SDK Subscribe Events Error: Cannot set both startBlockId and startHeight.`
@@ -29,5 +36,5 @@ export function subscribeEvents({
       ix.subscribeEvents.heartbeatInterval = heartbeatInterval ?? null
       return Ok(ix)
     },
-  ]) as any
+  ])
 }
diff --git a/packages/sdk/src/build/build-transaction.js b/packages/sdk/src/build/build-transaction.js
deleted file mode 100644
index 27b003d0..00000000
--- a/packages/sdk/src/build/build-transaction.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import {pipe, put, Ok, makeTransaction} from "../interaction/interaction"
-import {template} from "@onflow/util-template"
-
-const DEFAULT_SCRIPT_ACCOUNTS = []
-const DEFUALT_REF = null
-
-/**
- * @description - A template builder to use a Cadence transaction for an interaction
- * @param {...*} args - The arguments to pass
- * @returns {Function} - An interaction object
- */
-export function transaction(...args) {
-  return pipe([
-    makeTransaction,
-    put("ix.cadence", template(...args)),
-    ix => {
-      ix.message.refBlock = ix.message.refBlock || DEFUALT_REF
-      ix.authorizations = ix.authorizations || DEFAULT_SCRIPT_ACCOUNTS
-      return Ok(ix)
-    },
-  ])
-}
diff --git a/packages/sdk/src/build/build-transaction.ts b/packages/sdk/src/build/build-transaction.ts
new file mode 100644
index 00000000..b58aa462
--- /dev/null
+++ b/packages/sdk/src/build/build-transaction.ts
@@ -0,0 +1,30 @@
+import {
+  pipe,
+  put,
+  Ok,
+  makeTransaction,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+import {template} from "@onflow/util-template"
+
+const DEFAULT_SCRIPT_ACCOUNTS: string[] = []
+const DEFAULT_REF = ""
+
+/**
+ * @description A template builder to use a Cadence transaction for an interaction
+ * @param args The arguments to pass
+ * @returns A function that processes an interaction object
+ */
+export function transaction(
+  ...args: [string | TemplateStringsArray, ...any[]]
+): InteractionBuilderFn {
+  return pipe([
+    makeTransaction,
+    put("ix.cadence", template(...args)),
+    ix => {
+      ix.message.refBlock = ix.message.refBlock || DEFAULT_REF
+      ix.authorizations = ix.authorizations || DEFAULT_SCRIPT_ACCOUNTS
+      return Ok(ix)
+    },
+  ])
+}
diff --git a/packages/sdk/src/build/build-validator.js b/packages/sdk/src/build/build-validator.js
deleted file mode 100644
index c55a4e7f..00000000
--- a/packages/sdk/src/build/build-validator.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import {update} from "../interaction/interaction"
-
-export function validator(cb) {
-  return update("ix.validators", validators =>
-    Array.isArray(validators) ? validators.push(cb) : [cb]
-  )
-}
diff --git a/packages/sdk/src/build/build-validator.ts b/packages/sdk/src/build/build-validator.ts
new file mode 100644
index 00000000..34f4c612
--- /dev/null
+++ b/packages/sdk/src/build/build-validator.ts
@@ -0,0 +1,12 @@
+import {update, InteractionBuilderFn} from "../interaction/interaction"
+
+/**
+ * @description A builder function that adds a validator to a transaction
+ * @param cb The validator function
+ * @returns A function that processes an interaction object
+ */
+export function validator(cb: Function): InteractionBuilderFn {
+  return update("ix.validators", (validators: Function | Function[]) =>
+    Array.isArray(validators) ? [...validators, cb] : [cb]
+  )
+}
diff --git a/packages/sdk/src/build/build-voucher-intercept.js b/packages/sdk/src/build/build-voucher-intercept.js
deleted file mode 100644
index ae939294..00000000
--- a/packages/sdk/src/build/build-voucher-intercept.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import {put} from "../interaction/interaction"
-
-export function voucherIntercept(fn) {
-  return put("ix.voucher-intercept", fn)
-}
diff --git a/packages/sdk/src/build/build-voucher-intercept.ts b/packages/sdk/src/build/build-voucher-intercept.ts
new file mode 100644
index 00000000..b8af8983
--- /dev/null
+++ b/packages/sdk/src/build/build-voucher-intercept.ts
@@ -0,0 +1,13 @@
+import {put, InteractionBuilderFn} from "../interaction/interaction"
+import {Voucher} from "../encode/encode"
+
+type VoucherInterceptFn = (voucher: Voucher) => any | Promise<any>
+
+/**
+ * @description A builder function that intercepts and modifies a voucher
+ * @param fn The function to intercept and modify the voucher
+ * @returns A function that processes an interaction object
+ */
+export function voucherIntercept(fn: VoucherInterceptFn): InteractionBuilderFn {
+  return put("ix.voucher-intercept", fn)
+}
diff --git a/packages/sdk/src/build/build.js b/packages/sdk/src/build/build.js
deleted file mode 100644
index c7c3b272..00000000
--- a/packages/sdk/src/build/build.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import {pipe, initInteraction} from "../interaction/interaction"
-
-export function build(fns = []) {
-  return pipe(initInteraction(), fns)
-}
diff --git a/packages/sdk/src/build/build.ts b/packages/sdk/src/build/build.ts
new file mode 100644
index 00000000..1efe9491
--- /dev/null
+++ b/packages/sdk/src/build/build.ts
@@ -0,0 +1,17 @@
+import {
+  pipe,
+  initInteraction,
+  InteractionBuilderFn,
+} from "../interaction/interaction"
+import {Interaction} from "@onflow/typedefs"
+
+/**
+ * @description A builder function that creates an interaction
+ * @param fns The functions to apply to the interaction
+ * @returns A promise of an interaction
+ */
+export function build(
+  fns: (InteractionBuilderFn | false)[] = []
+): Promise<Interaction> {
+  return pipe(initInteraction(), fns)
+}
diff --git a/packages/sdk/src/decode/decode.js b/packages/sdk/src/decode/decode.ts
similarity index 59%
rename from packages/sdk/src/decode/decode.js
rename to packages/sdk/src/decode/decode.ts
index 1d211e23..11fcb8b4 100644
--- a/packages/sdk/src/decode/decode.js
+++ b/packages/sdk/src/decode/decode.ts
@@ -1,7 +1,85 @@
 import {log} from "@onflow/util-logger"
 import {decodeStream} from "./decode-stream"
 
-const latestBlockDeprecationNotice = () => {
+type DecoderFunction = (
+  value: any,
+  decoders: DecoderMap,
+  stack: any[]
+) => Promise<any>
+
+interface DecoderMap {
+  [key: string]: DecoderFunction
+}
+
+interface DecodeInstructions {
+  type: string
+  value?: any
+}
+
+interface CompositeField {
+  name: string
+  value: DecodeInstructions
+}
+
+interface CompositeInstruction {
+  id?: string
+  fields: CompositeField[]
+}
+
+interface KeyValuePair {
+  key: DecodeInstructions
+  value: DecodeInstructions
+}
+
+interface InclusiveRangeValue {
+  start?: DecodeInstructions
+  end?: DecodeInstructions
+  step?: DecodeInstructions
+  [key: string]: any
+}
+
+interface FlowEvent {
+  type: string
+  transactionId: string
+  transactionIndex: number
+  eventIndex: number
+  payload: DecodeInstructions
+}
+
+interface FlowBlockEvent extends FlowEvent {
+  blockId: string
+  blockHeight: number
+  blockTimestamp: string
+}
+
+interface FlowTransactionStatus {
+  blockId: string
+  status: number
+  statusCode: number
+  errorMessage: string
+  events: FlowEvent[]
+}
+
+interface FlowResponse {
+  encodedData?: DecodeInstructions
+  transactionStatus?: FlowTransactionStatus
+  transaction?: any
+  events?: FlowBlockEvent[]
+  account?: any
+  block?: any
+  blockHeader?: any
+  latestBlock?: any
+  transactionId?: string
+  collection?: any
+  networkParameters?: {
+    chainId: string
+  }
+  streamConnection?: any
+  heartbeat?: any
+  nodeVersionInfo?: any
+}
+
+const latestBlockDeprecationNotice = (): void => {
   log.deprecate({
     pkg: "@onflow/decode",
     subject:
@@ -11,7 +89,11 @@ const latestBlockDeprecationNotice = () => {
   })
 }
 
-const decodeNumber = async (num, _, stack) => {
+const decodeNumber = async (
+  num: any,
+  _: DecoderMap,
+  stack: any[]
+): Promise<number> => {
   try {
     return Number(num)
   } catch (e) {
@@ -19,18 +101,26 @@ const decodeNumber = async (num, _, stack) => {
   }
 }
 
-const decodeImplicit = async i => i
+const decodeImplicit = async <T>(i: T): Promise<T> => i
 
-const decodeVoid = async () => null
+const decodeVoid = async (): Promise<null> => null
 
-const decodeType = async type => {
+const decodeType = async (type: any): Promise<any> => {
   return type.staticType
 }
 
-const decodeOptional = async (optional, decoders, stack) =>
+const decodeOptional = async (
+  optional: any,
+  decoders: DecoderMap,
+  stack: any[]
+): Promise<any> =>
   optional ? await recurseDecode(optional, decoders, stack) : null
 
-const decodeArray = async (array, decoders, stack) =>
+const decodeArray = async (
+  array: DecodeInstructions[],
+  decoders: DecoderMap,
+  stack: any[]
+): Promise<any[]> =>
   await Promise.all(
     array.map(
       v =>
@@ -40,40 +130,61 @@ const decodeArray = async (array, decoders, stack) =>
     )
   )
 
-const decodeDictionary = async (dictionary, decoders, stack) =>
-  await dictionary.reduce(async (acc, v) => {
-    acc = await acc
-    acc[await recurseDecode(v.key, decoders, [...stack, v.key])] =
-      await recurseDecode(v.value, decoders, [...stack, v.key])
-    return acc
-  }, Promise.resolve({}))
-
-const decodeComposite = async (composite, decoders, stack) => {
-  const decoded = await composite.fields.reduce(async (acc, v) => {
-    acc = await acc
-    acc[v.name] = await recurseDecode(v.value, decoders, [...stack, v.name])
-    return acc
-  }, Promise.resolve({}))
+const decodeDictionary = async (
+  dictionary: KeyValuePair[],
+  decoders: DecoderMap,
+  stack: any[]
+): Promise<Record<string, any>> =>
+  await dictionary.reduce(
+    async (acc, v) => {
+      acc = await acc
+      acc[await recurseDecode(v.key, decoders, [...stack, v.key])] =
+        await recurseDecode(v.value, decoders, [...stack, v.key])
+      return acc
+    },
+    Promise.resolve({}) as any
+  )
+
+const decodeComposite = async (
+  composite: CompositeInstruction,
+  decoders: DecoderMap,
+  stack: any[]
+): Promise<any> => {
+  const decoded = await composite.fields.reduce(
+    async (acc, v) => {
+      acc = await acc
+      acc[v.name] = await recurseDecode(v.value, decoders, [...stack, v.name])
+      return acc
+    },
+    Promise.resolve({}) as any
+  )
   const decoder = composite.id && decoderLookup(decoders, composite.id)
   return decoder ? await decoder(decoded) : decoded
 }
 
-const decodeInclusiveRange = async (range, decoders, stack) => {
+const decodeInclusiveRange = async (
+  range: InclusiveRangeValue,
+  decoders: DecoderMap,
+  stack: any[]
+): Promise<Record<string, any>> => {
   // Recursive decode for start, end, and step
   // We don't do all fields just in case there are future API changes
   // where fields added and are not Cadence values
   const keys = ["start", "end", "step"]
-  const decoded = await Object.keys(range).reduce(async (acc, key) => {
-    acc = await acc
-    if (keys.includes(key)) {
-      acc[key] = await recurseDecode(range[key], decoders, [...stack, key])
-    }
-    return acc
-  }, Promise.resolve({}))
+  const decoded = await Object.keys(range).reduce(
+    async (acc, key) => {
+      acc = await acc
+      if (keys.includes(key)) {
+        acc[key] = await recurseDecode(range[key], decoders, [...stack, key])
+      }
+      return acc
+    },
+    Promise.resolve({}) as any
+  )
   return decoded
 }
 
-const defaultDecoders = {
+const defaultDecoders: DecoderMap = {
   UInt: decodeImplicit,
   Int: decodeImplicit,
   UInt8: decodeImplicit,
@@ -115,7 +226,7 @@ const defaultDecoders = {
   InclusiveRange: decodeInclusiveRange,
 }
 
-const decoderLookup = (decoders, lookup) => {
+const decoderLookup = (decoders: DecoderMap, lookup: any): any => {
   const found = Object.keys(decoders).find(decoder => {
     if (/^\/.*\/$/.test(decoder)) {
       const reg = new RegExp(decoder.substring(1, decoder.length - 1))
@@ -126,7 +237,11 @@ const decoderLookup = (decoders, lookup) => {
   return lookup && found && decoders[found]
 }
 
-const recurseDecode = async (decodeInstructions, decoders, stack) => {
+const recurseDecode = async (
+  decodeInstructions: DecodeInstructions,
+  decoders: DecoderMap,
+  stack: any[]
+): Promise<any> => {
   let decoder = decoderLookup(decoders, decodeInstructions.type)
   if (!decoder)
     throw new Error(
@@ -137,16 +252,16 @@ const recurseDecode = async (decodeInstructions, decoders, stack) => {
 
 /**
  * @description - Decodes a response from Flow into JSON
- * @param {*} decodeInstructions - The response object from Flow
- * @param {object} customDecoders - An object of custom decoders
- * @param {Array<*>} stack - The stack of the current decoding
- * @returns {Promise<*>} - The decoded response
+ * @param decodeInstructions - The response object from Flow
+ * @param customDecoders - An object of custom decoders
+ * @param stack - The stack of the current decoding
+ * @returns - The decoded response
  */
 export const decode = async (
-  decodeInstructions,
-  customDecoders = {},
-  stack = []
-) => {
+  decodeInstructions: DecodeInstructions,
+  customDecoders: DecoderMap = {},
+  stack: any[] = []
+): Promise<any> => {
   // Filter out all default decoders which are overridden by a custom decoder regex
   const filteredDecoders = Object.keys(defaultDecoders)
     .filter(
@@ -167,7 +282,10 @@ export const decode = async (
   return recurseDecode(decodeInstructions, decoders, stack)
 }
 
-export const decodeResponse = async (response, customDecoders = {}) => {
+export const decodeResponse = async (
+  response: FlowResponse,
+  customDecoders: DecoderMap = {}
+): Promise<any> => {
   if (response.encodedData) {
     return decode(response.encodedData, customDecoders)
   } else if (response.transactionStatus) {
@@ -218,7 +336,7 @@ export const decodeResponse = async (response, customDecoders = {}) => {
   } else if (response.networkParameters) {
     const prefixRegex = /^flow-/
     const rawChainId = response.networkParameters.chainId
-    let formattedChainId
+    let formattedChainId: string
 
     if (rawChainId === "flow-emulator") {
       formattedChainId = "local"
diff --git a/packages/sdk/src/decode/sdk-decode.js b/packages/sdk/src/decode/sdk-decode.ts
similarity index 86%
rename from packages/sdk/src/decode/sdk-decode.js
rename to packages/sdk/src/decode/sdk-decode.ts
index 6a1db6b7..58c10305 100644
--- a/packages/sdk/src/decode/sdk-decode.js
+++ b/packages/sdk/src/decode/sdk-decode.ts
@@ -1,7 +1,7 @@
 import {config} from "@onflow/config"
 import {decodeResponse} from "./decode"
 
-export async function decode(response) {
+export async function decode(response: any): Promise<any> {
   const decodersFromConfig = await config().where(/^decoder\./)
   const decoders = Object.entries(decodersFromConfig).map(
     ([pattern, xform]) => {
diff --git a/packages/sdk/src/interaction/interaction.test.ts b/packages/sdk/src/interaction/interaction.test.ts
index cb2a5b9a..f170e76b 100644
--- a/packages/sdk/src/interaction/interaction.test.ts
+++ b/packages/sdk/src/interaction/interaction.test.ts
@@ -1,4 +1,4 @@
-import {InteractionAccount} from "@onflow/typedefs"
+import {InteractionAccount, TransactionRole} from "@onflow/typedefs"
 import {resolveAccounts} from "../sdk"
 import {prepAccount, initAccount, initInteraction} from "./interaction"
 
@@ -15,7 +15,7 @@ describe("prepAccount", () => {
       }),
     }
 
-    const ix = prepAccount(acct, {role: "proposer"})({
+    const ix = prepAccount(acct, {role: TransactionRole.PROPOSER})({
       ...initInteraction(),
       accounts: {},
     })
@@ -37,13 +37,14 @@ describe("prepAccount", () => {
     }
 
     const ix = await resolveAccounts(
-      prepAccount(authz, {role: "proposer"})({
+      prepAccount(authz, {role: TransactionRole.PROPOSER})({
         ...initInteraction(),
         accounts: {},
       })
     )
-    ix.accounts[ix.proposer] = await ix.accounts[ix.proposer].resolve()
-    expect(ix.accounts[ix.proposer].keyId).toBe(parseInt(keyId))
+    ix.accounts[ix.proposer || ""] =
+      await ix.accounts[ix.proposer || ""].resolve()
+    expect(ix.accounts[ix.proposer || ""].keyId).toBe(parseInt(keyId))
   })
 
   test("prepAccount does not affect keyId if undefined/does not exist", async () => {
@@ -59,12 +60,13 @@ describe("prepAccount", () => {
     }
 
     const ix = await resolveAccounts(
-      prepAccount(authz, {role: "proposer"})({
+      prepAccount(authz, {role: TransactionRole.PROPOSER})({
         ...initInteraction(),
         accounts: {},
       })
     )
-    ix.accounts[ix.proposer] = await ix.accounts[ix.proposer].resolve()
-    expect(ix.accounts[ix.proposer].keyId).toBeUndefined()
+    ix.accounts[ix.proposer || ""] =
+      await ix.accounts[ix.proposer || ""].resolve()
+    expect(ix.accounts[ix.proposer || ""].keyId).toBeUndefined()
   })
 })
diff --git a/packages/sdk/src/interaction/interaction.ts b/packages/sdk/src/interaction/interaction.ts
index 74ecfd48..a4a022f8 100644
--- a/packages/sdk/src/interaction/interaction.ts
+++ b/packages/sdk/src/interaction/interaction.ts
@@ -10,10 +10,12 @@ import {
   InteractionStatus,
   InteractionTag,
 } from "@onflow/typedefs"
-import {TypeDescriptor, TypeDescriptorInput} from "@onflow/types"
+import {TypeDescriptorInput, TypeDescriptor} from "@onflow/types"
 
-type AcctFn = (acct: InteractionAccount) => InteractionAccount
-type AccountFn = AcctFn & Partial<InteractionAccount>
+export type AuthorizationFn = (acct: InteractionAccount) => InteractionAccount
+export type AccountAuthorization =
+  | (AuthorizationFn & Partial<InteractionAccount>)
+  | Partial<InteractionAccount>
 
 type CadenceArgument<T extends TypeDescriptor<any, any>> = {
   value: TypeDescriptorInput<T>
@@ -22,6 +24,10 @@ type CadenceArgument<T extends TypeDescriptor<any, any>> = {
 
 export {CadenceArgument}
 
+export type InteractionBuilderFn = (
+  ix: Interaction
+) => Interaction | Promise<Interaction>
+
 const ACCT = `{
   "kind":"${InteractionResolverKind.ACCOUNT}",
   "tempId":null,
@@ -146,9 +152,7 @@ const makeIx = (wat: InteractionTag) => (ix: Interaction) => {
   return Ok(ix)
 }
 
-const prepAccountKeyId = (
-  acct: Partial<InteractionAccount> | AccountFn
-): Partial<InteractionAccount> | AccountFn => {
+const prepAccountKeyId = (acct: AccountAuthorization): AccountAuthorization => {
   if (acct.keyId == null) return acct
 
   invariant(
@@ -159,7 +163,7 @@ const prepAccountKeyId = (
   return {
     ...acct,
     keyId: parseInt(acct.keyId.toString()),
-  } as InteractionAccount | AccountFn
+  } as AccountAuthorization
 }
 
 interface IPrepAccountOpts {
@@ -169,7 +173,7 @@ interface IPrepAccountOpts {
 export const initAccount = (): InteractionAccount => JSON.parse(ACCT)
 
 export const prepAccount =
-  (acct: InteractionAccount | AccountFn, opts: IPrepAccountOpts = {}) =>
+  (acct: AccountAuthorization, opts: IPrepAccountOpts = {}) =>
   (ix: Interaction) => {
     invariant(
       typeof acct === "function" || typeof acct === "object",
@@ -324,10 +328,7 @@ type MaybePromise<T> = T | Promise<T>
 
 const recPipe = async (
   ix: MaybePromise<Interaction>,
-  fns: (
-    | ((x: Interaction) => MaybePromise<Interaction>)
-    | MaybePromise<Interaction>
-  )[] = []
+  fns: (InteractionBuilderFn | false | MaybePromise<Interaction>)[] = []
 ): Promise<Interaction> => {
   try {
     ix = hardMode(await ix)
@@ -348,22 +349,16 @@ const recPipe = async (
  * @description Async pipe function to compose interactions
  * @returns An interaction object
  */
-function pipe(
-  fns: ((x: Interaction) => Interaction)[]
-): (x: Interaction) => Promise<Interaction>
-/**
- * @description Async pipe function to compose interactions
- * @returns An interaction object
- */
+function pipe(fns: (InteractionBuilderFn | false)[]): InteractionBuilderFn
 function pipe(
   ix: MaybePromise<Interaction>,
-  fns: ((x: Interaction) => Interaction)[]
+  fns: (InteractionBuilderFn | false)[]
 ): Promise<Interaction>
 function pipe(
   ...args:
-    | [((x: Interaction) => Interaction)[]]
-    | [MaybePromise<Interaction>, ((x: Interaction) => Interaction)[]]
-): Promise<Interaction> | ((x: Interaction) => Promise<Interaction>) {
+    | [(InteractionBuilderFn | false)[]]
+    | [MaybePromise<Interaction>, (InteractionBuilderFn | false)[]]
+): Promise<Interaction> | InteractionBuilderFn {
   const [arg1, arg2] = args
   if (isArray(arg1)) return (d: Interaction) => pipe(d, arg1)
 
@@ -385,7 +380,7 @@ export const put = (key: string, value: any) => (ix: Interaction) => {
 }
 
 export const update =
-  (key: string, fn = identity) =>
+  <T>(key: string, fn: (v: T | T[], ...args: any[]) => T | T[] = identity) =>
   (ix: Interaction) => {
     ix.assigns[key] = fn(ix.assigns[key], ix)
     return Ok(ix)
diff --git a/packages/sdk/src/node-version-info/node-version-info.ts b/packages/sdk/src/node-version-info/node-version-info.ts
index c905a76c..ef79948c 100644
--- a/packages/sdk/src/node-version-info/node-version-info.ts
+++ b/packages/sdk/src/node-version-info/node-version-info.ts
@@ -1,7 +1,7 @@
-import {send} from "../send/send.js"
-import {decodeResponse as decode} from "../decode/decode.js"
-import {getNodeVersionInfo} from "../build/build-get-node-version-info"
 import {NodeVersionInfo} from "@onflow/typedefs"
+import {getNodeVersionInfo} from "../build/build-get-node-version-info"
+import {decodeResponse as decode} from "../decode/decode"
+import {send} from "../send/send"
 
 /**
  * @description Returns the version information from to connected node
@@ -10,5 +10,6 @@ import {NodeVersionInfo} from "@onflow/typedefs"
 export async function nodeVersionInfo(
   opts: any = {}
 ): Promise<NodeVersionInfo> {
-  return send([getNodeVersionInfo()], opts).then(decode)
+  const ix = await send([getNodeVersionInfo()], opts)
+  return decode(ix)
 }
diff --git a/packages/sdk/src/resolve/__snapshots__/resolve-signatures.test.js.snap b/packages/sdk/src/resolve/__snapshots__/resolve-signatures.test.ts.snap
similarity index 95%
rename from packages/sdk/src/resolve/__snapshots__/resolve-signatures.test.js.snap
rename to packages/sdk/src/resolve/__snapshots__/resolve-signatures.test.ts.snap
index c448c6c5..cae19e89 100644
--- a/packages/sdk/src/resolve/__snapshots__/resolve-signatures.test.js.snap
+++ b/packages/sdk/src/resolve/__snapshots__/resolve-signatures.test.ts.snap
@@ -5,6 +5,7 @@ exports[`Golden Path 1`] = `
   "accounts": {
     "foo": {
       "addr": "foo",
+      "authorization": [Function],
       "keyId": 1,
       "kind": "ACCOUNT",
       "resolve": null,
@@ -84,11 +85,13 @@ exports[`Golden Path 1`] = `
     "cadence": "",
     "computeLimit": 156,
     "params": [],
-    "payer": null,
-    "proposer": null,
+    "payer": "",
+    "proposer": "",
     "refBlock": "123",
   },
-  "payer": "foo",
+  "payer": [
+    "foo",
+  ],
   "proposer": "foo",
   "tag": "TRANSACTION",
 }
diff --git a/packages/sdk/src/resolve/resolve-arguments.js b/packages/sdk/src/resolve/resolve-arguments.ts
similarity index 63%
rename from packages/sdk/src/resolve/resolve-arguments.js
rename to packages/sdk/src/resolve/resolve-arguments.ts
index eb1ad392..7b3b1aaf 100644
--- a/packages/sdk/src/resolve/resolve-arguments.js
+++ b/packages/sdk/src/resolve/resolve-arguments.ts
@@ -1,9 +1,18 @@
 import {invariant} from "@onflow/util-invariant"
 import {isTransaction, isScript} from "../interaction/interaction"
+import {Interaction} from "@onflow/typedefs"
+
+interface Argument {
+  tempId: string
+  value: any
+  xform: any
+  resolveArgument?: () => Promise<Argument>
+  asArgument?: any
+}
 
-const isFn = v => typeof v === "function"
+const isFn = (v: any): v is Function => typeof v === "function"
 
-function cast(arg) {
+function cast(arg: Argument): any {
   // prettier-ignore
   invariant(typeof arg.xform != null, `No type specified for argument: ${arg.value}`)
 
@@ -14,7 +23,10 @@ function cast(arg) {
   invariant(false, `Invalid Argument`, arg)
 }
 
-async function handleArgResolution(arg, depth = 3) {
+async function handleArgResolution(
+  arg: Argument,
+  depth = 3
+): Promise<Argument> {
   invariant(
     depth > 0,
     `Argument Resolve Recursion Limit Exceeded for Arg: ${arg.tempId}`
@@ -28,10 +40,10 @@ async function handleArgResolution(arg, depth = 3) {
   }
 }
 
-export async function resolveArguments(ix) {
+export async function resolveArguments(ix: Interaction): Promise<Interaction> {
   if (isTransaction(ix) || isScript(ix)) {
     for (let [id, arg] of Object.entries(ix.arguments)) {
-      const res = await handleArgResolution(arg)
+      const res = await handleArgResolution(arg as Argument)
       ix.arguments[id].asArgument = cast(res)
     }
   }
diff --git a/packages/sdk/src/resolve/resolve-cadence.js b/packages/sdk/src/resolve/resolve-cadence.ts
similarity index 69%
rename from packages/sdk/src/resolve/resolve-cadence.js
rename to packages/sdk/src/resolve/resolve-cadence.ts
index 3da21cbb..78f6cf0e 100644
--- a/packages/sdk/src/resolve/resolve-cadence.js
+++ b/packages/sdk/src/resolve/resolve-cadence.ts
@@ -3,34 +3,37 @@ import {invariant} from "@onflow/util-invariant"
 import {config} from "@onflow/config"
 import * as logger from "@onflow/util-logger"
 import {withPrefix} from "@onflow/util-address"
+import {Interaction} from "@onflow/typedefs"
 
-const isFn = v => typeof v === "function"
-const isString = v => typeof v === "string"
+const isFn = (v: any): v is Function => typeof v === "function"
+const isString = (v: any): v is string => typeof v === "string"
 
-const oldIdentifierPatternFn = () => /\b(0x\w+)\b/g
-function isOldIdentifierSyntax(cadence) {
+const oldIdentifierPatternFn = (): RegExp => /\b(0x\w+)\b/g
+function isOldIdentifierSyntax(cadence: string): boolean {
   return oldIdentifierPatternFn().test(cadence)
 }
 
-const newIdentifierPatternFn = () => /import\s+"(\w+)"/g
-function isNewIdentifierSyntax(cadence) {
+const newIdentifierPatternFn = (): RegExp => /import\s+"(\w+)"/g
+function isNewIdentifierSyntax(cadence: string): boolean {
   return newIdentifierPatternFn().test(cadence)
 }
 
-function getContractIdentifierSyntaxMatches(cadence) {
+function getContractIdentifierSyntaxMatches(
+  cadence: string
+): IterableIterator<RegExpMatchArray> {
   return cadence.matchAll(newIdentifierPatternFn())
 }
 
-export async function resolveCadence(ix) {
+export async function resolveCadence(ix: Interaction): Promise<Interaction> {
   if (!isTransaction(ix) && !isScript(ix)) return ix
 
-  var cadence = get(ix, "ix.cadence")
+  var cadence = get(ix, "ix.cadence", null)
 
   invariant(
     isFn(cadence) || isString(cadence),
     "Cadence needs to be a function or a string."
   )
-  if (isFn(cadence)) cadence = await cadence({})
+  if (isFn(cadence)) cadence = await cadence({} as Record<string, never>)
   invariant(isString(cadence), "Cadence needs to be a string at this point.")
   invariant(
     !isOldIdentifierSyntax(cadence) || !isNewIdentifierSyntax(cadence),
@@ -51,7 +54,9 @@ export async function resolveCadence(ix) {
     for (const [fullMatch, contractName] of getContractIdentifierSyntaxMatches(
       cadence
     )) {
-      const address = await config().get(`system.contracts.${contractName}`)
+      const address: string | null = await config().get(
+        `system.contracts.${contractName}`
+      )
       if (address) {
         cadence = cadence.replace(
           fullMatch,
diff --git a/packages/sdk/src/resolve/resolve-compute-limit.js b/packages/sdk/src/resolve/resolve-compute-limit.ts
similarity index 84%
rename from packages/sdk/src/resolve/resolve-compute-limit.js
rename to packages/sdk/src/resolve/resolve-compute-limit.ts
index a93cd58c..7e693c7e 100644
--- a/packages/sdk/src/resolve/resolve-compute-limit.js
+++ b/packages/sdk/src/resolve/resolve-compute-limit.ts
@@ -1,10 +1,13 @@
 import {isTransaction} from "../interaction/interaction"
 import {config} from "@onflow/config"
 import * as logger from "@onflow/util-logger"
+import {Interaction} from "@onflow/typedefs"
 
 const DEFAULT_COMPUTE_LIMIT = 100
 
-export async function resolveComputeLimit(ix) {
+export async function resolveComputeLimit(
+  ix: Interaction
+): Promise<Interaction> {
   if (isTransaction(ix)) {
     ix.message.computeLimit =
       ix.message.computeLimit || (await config.get("fcl.limit"))
diff --git a/packages/sdk/src/resolve/resolve-final-normalization.js b/packages/sdk/src/resolve/resolve-final-normalization.ts
similarity index 55%
rename from packages/sdk/src/resolve/resolve-final-normalization.js
rename to packages/sdk/src/resolve/resolve-final-normalization.ts
index 93a8cb2b..f7593d13 100644
--- a/packages/sdk/src/resolve/resolve-final-normalization.js
+++ b/packages/sdk/src/resolve/resolve-final-normalization.ts
@@ -1,6 +1,9 @@
 import {sansPrefix} from "@onflow/util-address"
+import {Interaction} from "@onflow/typedefs"
 
-export async function resolveFinalNormalization(ix) {
+export async function resolveFinalNormalization(
+  ix: Interaction
+): Promise<Interaction> {
   for (let key of Object.keys(ix.accounts)) {
     ix.accounts[key].addr = sansPrefix(ix.accounts[key].addr)
   }
diff --git a/packages/sdk/src/resolve/resolve-proposer-sequence-number.test.ts b/packages/sdk/src/resolve/resolve-proposer-sequence-number.test.ts
new file mode 100644
index 00000000..8c2e82ea
--- /dev/null
+++ b/packages/sdk/src/resolve/resolve-proposer-sequence-number.test.ts
@@ -0,0 +1,3 @@
+test("placeholder", () => {
+  expect(0).toBe(0)
+})
diff --git a/packages/sdk/src/resolve/resolve-proposer-sequence-number.js b/packages/sdk/src/resolve/resolve-proposer-sequence-number.ts
similarity index 60%
rename from packages/sdk/src/resolve/resolve-proposer-sequence-number.js
rename to packages/sdk/src/resolve/resolve-proposer-sequence-number.ts
index 4ec55db7..73abe0e8 100644
--- a/packages/sdk/src/resolve/resolve-proposer-sequence-number.js
+++ b/packages/sdk/src/resolve/resolve-proposer-sequence-number.ts
@@ -2,38 +2,43 @@ import {isTransaction, Ok} from "../interaction/interaction"
 import * as ixModule from "../interaction/interaction"
 import {response as responseModule} from "../response/response"
 import {config} from "@onflow/config"
-import {decodeResponse} from "../decode/decode.js"
-import {getAccount} from "../build/build-get-account.js"
-import {build} from "../build/build.js"
+import {decodeResponse} from "../decode/decode"
+import {getAccount} from "../build/build-get-account"
+import {build} from "../build/build"
 import {invariant} from "@onflow/util-invariant"
 import {Buffer} from "@onflow/rlp"
 import {send as defaultSend} from "@onflow/transport-http"
+import {Interaction} from "@onflow/typedefs"
+
+interface NodeConfig {
+  node: string
+}
 
 export const resolveProposerSequenceNumber =
-  ({node}) =>
-  async ix => {
+  ({node}: NodeConfig) =>
+  async (ix: Interaction) => {
     if (!isTransaction(ix)) return Ok(ix)
-    if (ix.accounts[ix.proposer].sequenceNum) return Ok(ix)
+    if (ix.accounts[ix.proposer!].sequenceNum) return Ok(ix)
 
-    const sendFn = await config.first(
+    const sendFn: any = await config.first(
       ["sdk.transport", "sdk.send"],
       defaultSend
     )
 
     invariant(
-      sendFn,
+      sendFn != null,
       `Required value for sdk.transport is not defined in config. See: ${"https://github.com/onflow/fcl-js/blob/master/packages/sdk/CHANGELOG.md#0057-alpha1----2022-01-21"}`
     )
 
     const response = await sendFn(
-      await build([getAccount(ix.accounts[ix.proposer].addr)]),
+      await build([getAccount(ix.accounts[ix.proposer!].addr!)]),
       {config, response: responseModule, Buffer, ix: ixModule},
       {node}
     )
     const decoded = await decodeResponse(response)
 
-    ix.accounts[ix.proposer].sequenceNum =
-      decoded.keys[ix.accounts[ix.proposer].keyId].sequenceNumber
+    ix.accounts[ix.proposer!].sequenceNum =
+      decoded.keys[ix.accounts[ix.proposer!].keyId!].sequenceNumber
 
     return Ok(ix)
   }
diff --git a/packages/sdk/src/resolve/resolve-ref-block-id.js b/packages/sdk/src/resolve/resolve-ref-block-id.ts
similarity index 72%
rename from packages/sdk/src/resolve/resolve-ref-block-id.js
rename to packages/sdk/src/resolve/resolve-ref-block-id.ts
index 0a11e1c8..c9413961 100644
--- a/packages/sdk/src/resolve/resolve-ref-block-id.js
+++ b/packages/sdk/src/resolve/resolve-ref-block-id.ts
@@ -7,15 +7,18 @@ import {
 import * as ixModule from "../interaction/interaction"
 import {response} from "../response/response"
 import {config} from "@onflow/config"
-import {decodeResponse} from "../decode/decode.js"
-import {getBlock} from "../build/build-get-block.js"
+import {decodeResponse} from "../decode/decode"
+import {getBlock} from "../build/build-get-block"
 import {invariant} from "@onflow/util-invariant"
 import {Buffer} from "@onflow/rlp"
 import {send as defaultSend} from "@onflow/transport-http"
 
-async function getRefId(opts) {
+async function getRefId(opts?: {[key: string]: any}): Promise<string> {
   const node = await config().get("accessNode.api")
-  const sendFn = await config.first(["sdk.transport", "sdk.send"], defaultSend)
+  const sendFn: any = await config.first(
+    ["sdk.transport", "sdk.send"],
+    defaultSend
+  )
 
   invariant(
     sendFn,
@@ -29,8 +32,8 @@ async function getRefId(opts) {
   return ix.id
 }
 
-export function resolveRefBlockId(opts) {
-  return async ix => {
+export function resolveRefBlockId(opts?: {[key: string]: any}) {
+  return async (ix: any) => {
     if (!isTransaction(ix)) return Ok(ix)
     if (ix.message.refBlock) return Ok(ix)
 
diff --git a/packages/sdk/src/resolve/resolve-validators.js b/packages/sdk/src/resolve/resolve-validators.js
deleted file mode 100644
index f86ebd02..00000000
--- a/packages/sdk/src/resolve/resolve-validators.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import {get, pipe, Ok, Bad} from "../interaction/interaction"
-
-export async function resolveValidators(ix) {
-  const validators = get(ix, "ix.validators", [])
-  return pipe(
-    ix,
-    validators.map(cb => ix => cb(ix, {Ok, Bad}))
-  )
-}
diff --git a/packages/sdk/src/resolve/resolve-validators.test.ts b/packages/sdk/src/resolve/resolve-validators.test.ts
new file mode 100644
index 00000000..8c2e82ea
--- /dev/null
+++ b/packages/sdk/src/resolve/resolve-validators.test.ts
@@ -0,0 +1,3 @@
+test("placeholder", () => {
+  expect(0).toBe(0)
+})
diff --git a/packages/sdk/src/resolve/resolve-validators.ts b/packages/sdk/src/resolve/resolve-validators.ts
new file mode 100644
index 00000000..6ed6ba4c
--- /dev/null
+++ b/packages/sdk/src/resolve/resolve-validators.ts
@@ -0,0 +1,10 @@
+import {get, pipe, Ok, Bad} from "../interaction/interaction"
+import {Interaction} from "@onflow/typedefs"
+
+export async function resolveValidators(ix: Interaction): Promise<Interaction> {
+  const validators = get(ix, "ix.validators", [])
+  return pipe(
+    ix,
+    validators.map((cb: Function) => (ix: Interaction) => cb(ix, {Ok, Bad}))
+  )
+}
diff --git a/packages/sdk/src/resolve/resolve-voucher-intercept.js b/packages/sdk/src/resolve/resolve-voucher-intercept.js
deleted file mode 100644
index f1f6ac21..00000000
--- a/packages/sdk/src/resolve/resolve-voucher-intercept.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import {get, isFn} from "../interaction/interaction"
-import {createSignableVoucher} from "./voucher"
-
-export async function resolveVoucherIntercept(ix) {
-  const fn = get(ix, "ix.voucher-intercept")
-  if (isFn(fn)) {
-    await fn(createSignableVoucher(ix))
-  }
-  return ix
-}
diff --git a/packages/sdk/src/resolve/resolve-voucher-intercept.ts b/packages/sdk/src/resolve/resolve-voucher-intercept.ts
new file mode 100644
index 00000000..60c8d7d5
--- /dev/null
+++ b/packages/sdk/src/resolve/resolve-voucher-intercept.ts
@@ -0,0 +1,13 @@
+import {get, isFn} from "../interaction/interaction"
+import {Interaction} from "@onflow/typedefs"
+import {createSignableVoucher} from "./voucher"
+
+export async function resolveVoucherIntercept(
+  ix: Interaction
+): Promise<Interaction> {
+  const fn = get(ix, "ix.voucher-intercept", null)
+  if (isFn(fn)) {
+    await fn(createSignableVoucher(ix))
+  }
+  return ix
+}
diff --git a/packages/sdk/src/resolve/resolve.js b/packages/sdk/src/resolve/resolve.ts
similarity index 52%
rename from packages/sdk/src/resolve/resolve.js
rename to packages/sdk/src/resolve/resolve.ts
index d8c57c3b..acc326a1 100644
--- a/packages/sdk/src/resolve/resolve.js
+++ b/packages/sdk/src/resolve/resolve.ts
@@ -5,30 +5,33 @@ import {Buffer} from "@onflow/rlp"
 import {send as defaultSend} from "@onflow/transport-http"
 import * as ixModule from "../interaction/interaction"
 import {response} from "../response/response"
-import {build} from "../build/build.js"
-import {getBlock} from "../build/build-get-block.js"
-import {getAccount} from "../build/build-get-account.js"
-import {decodeResponse as decode} from "../decode/decode.js"
+import {build} from "../build/build"
+import {getBlock} from "../build/build-get-block"
+import {getAccount} from "../build/build-get-account"
+import {decodeResponse as decode} from "../decode/decode"
+import {Interaction} from "@onflow/typedefs"
 
-import {resolveCadence} from "./resolve-cadence.js"
-import {resolveArguments} from "./resolve-arguments.js"
+import {resolveCadence} from "./resolve-cadence"
+import {resolveArguments} from "./resolve-arguments"
 import {resolveAccounts} from "./resolve-accounts"
 import {resolveSignatures} from "./resolve-signatures"
-import {resolveValidators} from "./resolve-validators.js"
-import {resolveFinalNormalization} from "./resolve-final-normalization.js"
-import {resolveVoucherIntercept} from "./resolve-voucher-intercept.js"
-import {resolveComputeLimit} from "./resolve-compute-limit.js"
+import {resolveValidators} from "./resolve-validators"
+import {resolveFinalNormalization} from "./resolve-final-normalization"
+import {resolveVoucherIntercept} from "./resolve-voucher-intercept"
+import {resolveComputeLimit} from "./resolve-compute-limit"
 
-const noop = v => v
+type DebugCallback = (ix: Interaction, log: any, accts?: any) => any
+
+const noop = (v: any) => v
 const debug =
-  (key, fn = noop) =>
-  async ix => {
-    const take = (obj, keys = []) => {
+  (key: string, fn: DebugCallback = noop) =>
+  async (ix: Interaction): Promise<Interaction> => {
+    const take = (obj: any, keys: string | string[] = []) => {
       if (typeof keys === "string") keys = keys.split(" ")
       keys.reduce((acc, key) => ({...acc, [key]: obj[key]}), {})
     }
 
-    const accts = ix =>
+    const accts = (ix: Interaction) =>
       [
         "\nAccounts:",
         {
@@ -40,7 +43,7 @@ const debug =
         ix.accounts,
       ].filter(Boolean)
 
-    const log = (...msg) => {
+    const log = (...msg: any[]) => {
       console.log(`debug[${key}] ---\n`, ...msg, "\n\n\n---")
     }
 
@@ -50,33 +53,41 @@ const debug =
 
 export const resolve = pipe([
   resolveCadence,
-  debug("cadence", (ix, log) => log(ix.message.cadence)),
+  debug("cadence", (ix: Interaction, log: any) => log(ix.message.cadence)),
   resolveComputeLimit,
-  debug("compute limit", (ix, log) => log(ix.message.computeLimit)),
+  debug("compute limit", (ix: Interaction, log: any) =>
+    log(ix.message.computeLimit)
+  ),
   resolveArguments,
-  debug("arguments", (ix, log) => log(ix.message.arguments, ix.message)),
+  debug("arguments", (ix: Interaction, log: any) =>
+    log(ix.message.arguments, ix.message)
+  ),
   resolveAccounts,
-  debug("accounts", (ix, log, accts) => log(...accts(ix))),
+  debug("accounts", (ix: Interaction, log: any, accts: any) =>
+    log(...accts(ix))
+  ),
   /* special */ execFetchRef,
   /* special */ execFetchSequenceNumber,
   resolveSignatures,
-  debug("signatures", (ix, log, accts) => log(...accts(ix))),
+  debug("signatures", (ix: Interaction, log: any, accts: any) =>
+    log(...accts(ix))
+  ),
   resolveFinalNormalization,
   resolveValidators,
   resolveVoucherIntercept,
-  debug("resolved", (ix, log) => log(ix)),
+  debug("resolved", (ix: Interaction, log: any) => log(ix)),
 ])
 
-async function execFetchRef(ix) {
+async function execFetchRef(ix: Interaction): Promise<Interaction> {
   if (isTransaction(ix) && ix.message.refBlock == null) {
     const node = await config().get("accessNode.api")
-    const sendFn = await config.first(
+    const sendFn: any = await config.first(
       ["sdk.transport", "sdk.send"],
       defaultSend
     )
 
     invariant(
-      sendFn,
+      sendFn !== undefined,
       `Required value for sdk.transport is not defined in config. See: ${"https://github.com/onflow/fcl-js/blob/master/packages/sdk/CHANGELOG.md#0057-alpha1----2022-01-21"}`
     )
 
@@ -91,31 +102,35 @@ async function execFetchRef(ix) {
   return ix
 }
 
-async function execFetchSequenceNumber(ix) {
+async function execFetchSequenceNumber(ix: Interaction): Promise<Interaction> {
   if (isTransaction(ix)) {
-    var acct = Object.values(ix.accounts).find(a => a.role.proposer)
-    invariant(acct, `Transactions require a proposer`)
-    if (acct.sequenceNum == null) {
+    var acct = Object.values(ix.accounts).find((a: any) => a.role.proposer)
+    invariant(acct !== undefined, `Transactions require a proposer`)
+    if (acct && acct.sequenceNum == null) {
       const node = await config().get("accessNode.api")
-      const sendFn = await config.first(
+      const sendFn: any = await config.first(
         ["sdk.transport", "sdk.send"],
         defaultSend
       )
 
       invariant(
-        sendFn,
+        sendFn !== undefined,
         `Required value for sdk.transport is not defined in config. See: ${"https://github.com/onflow/fcl-js/blob/master/packages/sdk/CHANGELOG.md#0057-alpha1----2022-01-21"}`
       )
 
-      ix.accounts[acct.tempId].sequenceNum = await sendFn(
-        await build([getAccount(acct.addr)]),
+      const keyId = acct.keyId
+      const tempId = acct.tempId
+      const addr = acct.addr || ""
+
+      ix.accounts[tempId].sequenceNum = await sendFn(
+        await build([getAccount(addr)]),
         {config, response, Buffer, ix: ixModule},
         {node}
       )
         .then(decode)
-        .then(acct => acct.keys)
-        .then(keys => keys.find(key => key.index === acct.keyId))
-        .then(key => key.sequenceNumber)
+        .then((acctResponse: any) => acctResponse.keys)
+        .then((keys: any[]) => keys.find((key: any) => key.index === keyId))
+        .then((key: any) => key.sequenceNumber)
     }
   }
   return ix
diff --git a/packages/sdk/src/sdk.ts b/packages/sdk/src/sdk.ts
index 6676fa5f..82e0a98d 100644
--- a/packages/sdk/src/sdk.ts
+++ b/packages/sdk/src/sdk.ts
@@ -1,9 +1,9 @@
 import * as logger from "@onflow/util-logger"
 // Base
-export {build} from "./build/build.js"
-export {resolve} from "./resolve/resolve.js"
-export {send} from "./send/send.js"
-export {decode} from "./decode/sdk-decode.js"
+export {build} from "./build/build"
+export {resolve} from "./resolve/resolve"
+export {send} from "./send/send"
+export {decode} from "./decode/sdk-decode"
 export {
   encodeTransactionPayload,
   encodeTransactionEnvelope,
@@ -38,57 +38,62 @@ export {
 } from "./interaction/interaction"
 import type {CadenceArgument} from "./interaction/interaction"
 export {CadenceArgument} // Workaround for babel https://github.com/babel/babel/issues/8361
+import type {InteractionBuilderFn} from "./interaction/interaction"
+export {InteractionBuilderFn}
 
 export {createSignableVoucher, voucherToTxId} from "./resolve/voucher"
-export {encodeMessageFromSignable} from "./wallet-utils/encode-signable.js"
+export {encodeMessageFromSignable} from "./wallet-utils/encode-signable"
 export {template as cadence} from "@onflow/util-template"
 export {template as cdc} from "@onflow/util-template"
 
+import type {Voucher} from "./wallet-utils/encode-signable"
+export {Voucher}
+
 // Helpers
 export {account} from "./account/account"
-export {block} from "./block/block.js"
+export {block} from "./block/block"
 export {nodeVersionInfo} from "./node-version-info/node-version-info"
 
 // Builders
-export {authorizations, authorization} from "./build/build-authorizations.js"
-export {atBlockHeight} from "./build/build-at-block-height.js"
-export {atBlockId} from "./build/build-at-block-id.js"
-export {atLatestBlock} from "./build/build-at-latest-block.js"
-export {getAccount} from "./build/build-get-account.js"
-export {getEvents} from "./build/build-get-events.js"
-export {getEventsAtBlockHeightRange} from "./build/build-get-events-at-block-height-range.js"
+export {authorizations, authorization} from "./build/build-authorizations"
+export {atBlockHeight} from "./build/build-at-block-height"
+export {atBlockId} from "./build/build-at-block-id"
+export {atLatestBlock} from "./build/build-at-latest-block"
+export {getAccount} from "./build/build-get-account"
+export {getEvents} from "./build/build-get-events"
+export {getEventsAtBlockHeightRange} from "./build/build-get-events-at-block-height-range"
 export {getEventsAtBlockIds} from "./build/build-get-events-at-block-ids"
-export {getBlock} from "./build/build-get-block.js"
-export {getBlockHeader} from "./build/build-get-block-header.js"
+export {getBlock} from "./build/build-get-block"
+export {getBlockHeader} from "./build/build-get-block-header"
 export {getCollection} from "./build/build-get-collection"
-export {getTransactionStatus} from "./build/build-get-transaction-status.js"
-export {getTransaction} from "./build/build-get-transaction.js"
-export {getNetworkParameters} from "./build/build-get-network-parameters.js"
+export {getTransactionStatus} from "./build/build-get-transaction-status"
+export {getTransaction} from "./build/build-get-transaction"
+export {getNetworkParameters} from "./build/build-get-network-parameters"
 export {getNodeVersionInfo} from "./build/build-get-node-version-info"
-export {limit} from "./build/build-limit.js"
+export {limit} from "./build/build-limit"
 export {args, arg} from "./build/build-arguments"
-export {proposer} from "./build/build-proposer.js"
-export {payer} from "./build/build-payer.js"
-export {ping} from "./build/build-ping.js"
-export {ref} from "./build/build-ref.js"
-export {script} from "./build/build-script.js"
-export {transaction} from "./build/build-transaction.js"
-export {validator} from "./build/build-validator.js"
-export {invariant} from "./build/build-invariant.js"
-export {voucherIntercept} from "./build/build-voucher-intercept.js"
+export {proposer} from "./build/build-proposer"
+export {payer} from "./build/build-payer"
+export {ping} from "./build/build-ping"
+export {ref} from "./build/build-ref"
+export {script} from "./build/build-script"
+export {transaction} from "./build/build-transaction"
+export {validator} from "./build/build-validator"
+export {invariant} from "./build/build-invariant"
+export {voucherIntercept} from "./build/build-voucher-intercept"
 export {subscribeEvents} from "./build/build-subscribe-events"
 
 // Resolvers
-export {resolveCadence} from "./resolve/resolve-cadence.js"
+export {resolveCadence} from "./resolve/resolve-cadence"
 export {resolveFinalNormalization} from "./resolve/resolve-final-normalization"
 export {resolveProposerSequenceNumber} from "./resolve/resolve-proposer-sequence-number"
-export {resolveArguments} from "./resolve/resolve-arguments.js"
+export {resolveArguments} from "./resolve/resolve-arguments"
 export {resolveAccounts} from "./resolve/resolve-accounts"
 export {response} from "./response/response"
 export {resolveSignatures} from "./resolve/resolve-signatures"
-export {resolveValidators} from "./resolve/resolve-validators.js"
-export {resolveRefBlockId} from "./resolve/resolve-ref-block-id.js"
-export {resolveVoucherIntercept} from "./resolve/resolve-voucher-intercept.js"
+export {resolveValidators} from "./resolve/resolve-validators"
+export {resolveRefBlockId} from "./resolve/resolve-ref-block-id"
+export {resolveVoucherIntercept} from "./resolve/resolve-voucher-intercept"
 
 export {config} from "@onflow/config"
 
@@ -116,3 +121,8 @@ export {TestUtils}
 export {VERSION} from "./VERSION"
 
 export {flowMainnet, flowTestnet, flowEmulator} from "./constants"
+
+export * from "@onflow/typedefs"
+
+import * as types from "@onflow/types"
+export {types as t}
diff --git a/packages/sdk/src/send/send.js b/packages/sdk/src/send/send.js
deleted file mode 100644
index 1ed79a75..00000000
--- a/packages/sdk/src/send/send.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import {Buffer} from "@onflow/rlp"
-import {send as defaultSend} from "@onflow/transport-http"
-import {initInteraction, pipe} from "../interaction/interaction"
-import * as ixModule from "../interaction/interaction"
-import {invariant} from "../build/build-invariant.js"
-import {response} from "../response/response"
-import {config} from "@onflow/config"
-import {resolve as defaultResolve} from "../resolve/resolve.js"
-
-/**
- * @description - Sends arbitrary scripts, transactions, and requests to Flow
- * @param {Array.<Function | false> | Function | false} args - An array of functions that take interaction and return interaction
- * @param {object} opts - Optional parameters
- * @returns {Promise<*>} - A promise that resolves to a response
- */
-export const send = async (args = [], opts = {}) => {
-  const sendFn = await config.first(
-    ["sdk.transport", "sdk.send"],
-    opts.send || defaultSend
-  )
-
-  invariant(
-    sendFn,
-    `Required value for sdk.transport is not defined in config. See: ${"https://github.com/onflow/fcl-js/blob/master/packages/sdk/CHANGELOG.md#0057-alpha1----2022-01-21"}`
-  )
-
-  const resolveFn = await config.first(
-    ["sdk.resolve"],
-    opts.resolve || defaultResolve
-  )
-
-  opts.node = opts.node || (await config().get("accessNode.api"))
-
-  if (Array.isArray(args)) args = pipe(initInteraction(), args)
-  return sendFn(
-    await resolveFn(args),
-    {config, response, ix: ixModule, Buffer},
-    opts
-  )
-}
diff --git a/packages/sdk/src/send/send.ts b/packages/sdk/src/send/send.ts
new file mode 100644
index 00000000..0b65c551
--- /dev/null
+++ b/packages/sdk/src/send/send.ts
@@ -0,0 +1,53 @@
+import {config} from "@onflow/config"
+import {Buffer} from "@onflow/rlp"
+import {send as defaultSend} from "@onflow/transport-http"
+import {invariant} from "../build/build-invariant"
+import * as ixModule from "../interaction/interaction"
+import {
+  initInteraction,
+  InteractionBuilderFn,
+  pipe,
+} from "../interaction/interaction"
+import {resolve as defaultResolve} from "../resolve/resolve"
+import {response} from "../response/response"
+
+interface SendOptions {
+  send?: typeof defaultSend
+  resolve?: typeof defaultResolve
+  node?: string
+}
+
+/**
+ * @description Sends arbitrary scripts, transactions, and requests to Flow
+ * @param args An array of functions that take interaction and return interaction
+ * @param opts Optional parameters
+ * @returns A promise that resolves to a response
+ */
+export const send = async (
+  args: (InteractionBuilderFn | false)[] | InteractionBuilderFn | false,
+  opts: SendOptions = {}
+): Promise<any> => {
+  const sendFn = await config.first(
+    ["sdk.transport", "sdk.send"],
+    opts.send || defaultSend
+  )
+
+  invariant(
+    sendFn,
+    `Required value for sdk.transport is not defined in config. See: ${"https://github.com/onflow/fcl-js/blob/master/packages/sdk/CHANGELOG.md#0057-alpha1----2022-01-21"}`
+  )
+
+  const resolveFn: any = await config.first(
+    ["sdk.resolve"],
+    opts.resolve || defaultResolve
+  )
+
+  opts.node = opts.node || (await config().get("accessNode.api"))
+
+  if (Array.isArray(args)) args = pipe(initInteraction(), args as any) as any
+  return sendFn(
+    await resolveFn(args),
+    {config, response, ix: ixModule, Buffer} as any,
+    opts
+  )
+}
diff --git a/packages/sdk/src/test-utils/index.js b/packages/sdk/src/test-utils/index.ts
similarity index 100%
rename from packages/sdk/src/test-utils/index.js
rename to packages/sdk/src/test-utils/index.ts
diff --git a/packages/sdk/src/test-utils/run.js b/packages/sdk/src/test-utils/run.js
deleted file mode 100644
index 3ca7df44..00000000
--- a/packages/sdk/src/test-utils/run.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import {build} from "../build/build"
-import {resolve} from "../resolve/resolve"
-import {ref} from "../build/build-ref"
-
-export const run = (fns = []) => build([ref("123"), ...fns]).then(resolve)
diff --git a/packages/sdk/src/test-utils/run.ts b/packages/sdk/src/test-utils/run.ts
new file mode 100644
index 00000000..fbc70bf4
--- /dev/null
+++ b/packages/sdk/src/test-utils/run.ts
@@ -0,0 +1,8 @@
+import {build} from "../build/build"
+import {resolve} from "../resolve/resolve"
+import {ref} from "../build/build-ref"
+import {Interaction} from "@onflow/typedefs"
+
+export const run = (
+  fns: Array<(ix: Interaction) => Interaction | Promise<Interaction>> = []
+) => build([ref("123"), ...fns]).then(resolve)
diff --git a/packages/sdk/src/wallet-utils/encode-signable.js b/packages/sdk/src/wallet-utils/encode-signable.ts
similarity index 64%
rename from packages/sdk/src/wallet-utils/encode-signable.js
rename to packages/sdk/src/wallet-utils/encode-signable.ts
index 724c78d0..77253baa 100644
--- a/packages/sdk/src/wallet-utils/encode-signable.js
+++ b/packages/sdk/src/wallet-utils/encode-signable.ts
@@ -4,22 +4,55 @@ import {
   encodeTransactionEnvelope,
 } from "../encode/encode"
 
-const findPayloadSigners = voucher => {
+interface Sig {
+  address: string
+  keyId: number | string
+  sig: string
+}
+
+interface PayloadSig {
+  address: string
+  keyId: number | string
+  sig: string
+  [key: string]: any
+}
+
+export interface Voucher {
+  authorizers: string[]
+  proposalKey: {
+    address: string
+    keyId?: number | string
+    sequenceNum?: number
+    [key: string]: any
+  }
+  payer: string
+  cadence: string
+  refBlock: string
+  computeLimit: number
+  arguments: any[]
+  payloadSigs: PayloadSig[]
+}
+
+interface Signable {
+  voucher: Voucher
+}
+
+const findPayloadSigners = (voucher: Voucher): string[] => {
   // Payload Signers Are: (authorizers + proposer) - payer
-  let payload = new Set(voucher.authorizers)
+  const payload: Set<string> = new Set(voucher.authorizers)
   payload.add(voucher.proposalKey.address)
   payload.delete(voucher.payer)
-  return Array.from(payload).map(withPrefix)
+  return Array.from(payload).map(addr => withPrefix(addr))
 }
 
-const findEnvelopeSigners = voucher => {
+const findEnvelopeSigners = (voucher: Voucher): string[] => {
   // Envelope Signers Are: (payer)
-  let envelope = new Set([voucher.payer])
-  return Array.from(envelope).map(withPrefix)
+  const envelope: Set<string> = new Set([voucher.payer])
+  return Array.from(envelope).map(addr => withPrefix(addr))
 }
 
 export class UnableToDetermineMessageEncodingTypeForSignerAddress extends Error {
-  constructor(signerAddress) {
+  constructor(signerAddress: string) {
     const msg = `
         Encode Message From Signable Error: Unable to determine message encoding for signer addresss: ${signerAddress}. 
         Please ensure the address: ${signerAddress} is intended to sign the given transaction as specified by the transaction signable.
@@ -29,7 +62,10 @@ export class UnableToDetermineMessageEncodingTypeForSignerAddress extends Error
   }
 }
 
-export const encodeMessageFromSignable = (signable, signerAddress) => {
+export const encodeMessageFromSignable = (
+  signable: Signable,
+  signerAddress: string
+): string => {
   let payloadSigners = findPayloadSigners(signable.voucher)
   let envelopeSigners = findEnvelopeSigners(signable.voucher)
 
@@ -42,7 +78,7 @@ export const encodeMessageFromSignable = (signable, signerAddress) => {
     )
   }
 
-  const message = {
+  const message: any = {
     cadence: signable.voucher.cadence,
     refBlock: signable.voucher.refBlock,
     computeLimit: signable.voucher.computeLimit,
diff --git a/packages/sdk/src/wallet-utils/index.js b/packages/sdk/src/wallet-utils/index.js
deleted file mode 100644
index e3c4a24b..00000000
--- a/packages/sdk/src/wallet-utils/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export {validateSignableTransaction} from "./validate-tx.js"
-export {encodeMessageFromSignable} from "./encode-signable.js"
diff --git a/packages/sdk/src/wallet-utils/index.ts b/packages/sdk/src/wallet-utils/index.ts
new file mode 100644
index 00000000..0071d56c
--- /dev/null
+++ b/packages/sdk/src/wallet-utils/index.ts
@@ -0,0 +1,2 @@
+export {validateSignableTransaction} from "./validate-tx"
+export {encodeMessageFromSignable} from "./encode-signable"
diff --git a/packages/sdk/src/wallet-utils/validate-tx.js b/packages/sdk/src/wallet-utils/validate-tx.ts
similarity index 58%
rename from packages/sdk/src/wallet-utils/validate-tx.js
rename to packages/sdk/src/wallet-utils/validate-tx.ts
index 03b639d0..e8cff04d 100644
--- a/packages/sdk/src/wallet-utils/validate-tx.js
+++ b/packages/sdk/src/wallet-utils/validate-tx.ts
@@ -4,23 +4,33 @@ import {
 } from "../encode/encode"
 import {invariant} from "@onflow/util-invariant"
 
-const isPayer = signable => {
+interface Signable {
+  roles: {
+    payer: boolean
+  }
+  voucher: any
+  message: string
+}
+
+const isPayer = (signable: Signable): boolean => {
   return signable.roles.payer
 }
-const getVoucher = signable => {
+
+const getVoucher = (signable: Signable): any => {
   return signable.voucher
 }
-const getMessage = signable => {
+
+const getMessage = (signable: Signable): string => {
   return signable.message
 }
 
-const isExpectedMessage = signable => {
+const isExpectedMessage = (signable: Signable): boolean => {
   return isPayer(signable)
     ? encodeOutsideMessage(getVoucher(signable)) === getMessage(signable)
     : encodeInsideMessage(getVoucher(signable)) === getMessage(signable)
 }
 
-export const validateSignableTransaction = signable => {
+export const validateSignableTransaction = (signable: Signable): boolean => {
   invariant(isExpectedMessage(signable), "Signable payload must be transaction")
 
   return true
diff --git a/packages/typedefs/src/interaction.ts b/packages/typedefs/src/interaction.ts
index 0d45c8d7..3896cbde 100644
--- a/packages/typedefs/src/interaction.ts
+++ b/packages/typedefs/src/interaction.ts
@@ -72,8 +72,8 @@ export interface Interaction {
   payer: string[]
   events: {
     eventType: string | null
-    start: string | null
-    end: string | null
+    start: string | number | null
+    end: string | number | null
     blockIds: string[]
   }
   transaction: {
@@ -81,7 +81,7 @@ export interface Interaction {
   }
   block: {
     id: string | null
-    height: string | null
+    height: string | number | null
     isSealed: boolean | null
   }
   account: {



Test patch:
diff --git a/packages/sdk/src/account/account.test.js b/packages/sdk/src/account/account.test.ts
similarity index 100%
rename from packages/sdk/src/account/account.test.js
rename to packages/sdk/src/account/account.test.ts
diff --git a/packages/sdk/src/build/build-arguments.test.js b/packages/sdk/src/block/block.test.ts
similarity index 100%
rename from packages/sdk/src/build/build-arguments.test.js
rename to packages/sdk/src/block/block.test.ts
diff --git a/packages/sdk/src/build/build-get-events.test.js b/packages/sdk/src/build/build-arguments.test.ts
similarity index 100%
rename from packages/sdk/src/build/build-get-events.test.js
rename to packages/sdk/src/build/build-arguments.test.ts
diff --git a/packages/sdk/src/build/build-at-block-height.test.js b/packages/sdk/src/build/build-at-block-height.test.ts
similarity index 60%
rename from packages/sdk/src/build/build-at-block-height.test.js
rename to packages/sdk/src/build/build-at-block-height.test.ts
index d30830bc..2945c454 100644
--- a/packages/sdk/src/build/build-at-block-height.test.js
+++ b/packages/sdk/src/build/build-at-block-height.test.ts
@@ -1,8 +1,8 @@
 import {initInteraction} from "../interaction/interaction"
-import {atBlockHeight} from "./build-at-block-height.js"
+import {atBlockHeight} from "./build-at-block-height"
 
-describe("Build At Block ID", () => {
-  test("At Block ID", async () => {
+describe("Build At Block Height", () => {
+  test("At Block Height", async () => {
     const blockHeight = 123
 
     const ix = await atBlockHeight(blockHeight)(initInteraction())
diff --git a/packages/sdk/src/build/build-at-block-id.test.js b/packages/sdk/src/build/build-at-block-id.test.ts
similarity index 84%
rename from packages/sdk/src/build/build-at-block-id.test.js
rename to packages/sdk/src/build/build-at-block-id.test.ts
index 71738f04..82d0bf61 100644
--- a/packages/sdk/src/build/build-at-block-id.test.js
+++ b/packages/sdk/src/build/build-at-block-id.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction} from "../interaction/interaction"
-import {atBlockId} from "./build-at-block-id.js"
+import {atBlockId} from "./build-at-block-id"
 
 describe("Build At Block ID", () => {
   test("At Block ID", async () => {
diff --git a/packages/sdk/src/build/build-at-latest-block.test.js b/packages/sdk/src/build/build-at-latest-block.test.ts
similarity index 100%
rename from packages/sdk/src/build/build-at-latest-block.test.js
rename to packages/sdk/src/build/build-at-latest-block.test.ts
diff --git a/packages/sdk/src/build/build-authorizations.test.js b/packages/sdk/src/build/build-authorizations.test.ts
similarity index 85%
rename from packages/sdk/src/build/build-authorizations.test.js
rename to packages/sdk/src/build/build-authorizations.test.ts
index 6357f0b9..c51d6313 100644
--- a/packages/sdk/src/build/build-authorizations.test.js
+++ b/packages/sdk/src/build/build-authorizations.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction} from "../interaction/interaction"
-import {authorizations, authorization} from "./build-authorizations.js"
+import {authorizations, authorization} from "./build-authorizations"
 
 describe("Build Authorizations", () => {
   test("build authorizer", async () => {
@@ -9,7 +9,8 @@ describe("Build Authorizations", () => {
       ])
     )(initInteraction())
 
-    const authorizerAccount = ix.accounts[ix.authorizations]
+    const authorizerAccount =
+      ix.accounts[ix.authorizations as unknown as string]
 
     expect(authorizerAccount.addr).toEqual("0xabc123")
     expect(authorizerAccount.role).toEqual({
diff --git a/packages/sdk/src/build/build-get-account.test.js b/packages/sdk/src/build/build-get-account.test.ts
similarity index 92%
rename from packages/sdk/src/build/build-get-account.test.js
rename to packages/sdk/src/build/build-get-account.test.ts
index 125d328d..c0575b8e 100644
--- a/packages/sdk/src/build/build-get-account.test.js
+++ b/packages/sdk/src/build/build-get-account.test.ts
@@ -1,6 +1,6 @@
 import {initInteraction} from "../interaction/interaction"
 import {sansPrefix, withPrefix} from "@onflow/util-address"
-import {getAccount} from "./build-get-account.js"
+import {getAccount} from "./build-get-account"
 
 const ADDRESS = "0xf117a8efa34ffd58"
 
diff --git a/packages/sdk/src/build/build-get-block-header.test.js b/packages/sdk/src/build/build-get-block-header.test.ts
similarity index 91%
rename from packages/sdk/src/build/build-get-block-header.test.js
rename to packages/sdk/src/build/build-get-block-header.test.ts
index b82e09df..8d76c307 100644
--- a/packages/sdk/src/build/build-get-block-header.test.js
+++ b/packages/sdk/src/build/build-get-block-header.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isGetBlockHeader} from "../interaction/interaction"
-import {getBlockHeader} from "./build-get-block-header.js"
+import {getBlockHeader} from "./build-get-block-header"
 
 describe("Build Get Block Header", () => {
   test("Get Block Header, isSealed = false", async () => {
diff --git a/packages/sdk/src/build/build-get-block.test.js b/packages/sdk/src/build/build-get-block.test.ts
similarity index 92%
rename from packages/sdk/src/build/build-get-block.test.js
rename to packages/sdk/src/build/build-get-block.test.ts
index 7d43a19f..565efaca 100644
--- a/packages/sdk/src/build/build-get-block.test.js
+++ b/packages/sdk/src/build/build-get-block.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isGetBlock} from "../interaction/interaction"
-import {getBlock} from "./build-get-block.js"
+import {getBlock} from "./build-get-block"
 
 describe("Build Get Block", () => {
   test("Get Block - isSealed = false", async () => {
diff --git a/packages/sdk/src/build/build-get-collection.test.js b/packages/sdk/src/build/build-get-collection.test.ts
similarity index 86%
rename from packages/sdk/src/build/build-get-collection.test.js
rename to packages/sdk/src/build/build-get-collection.test.ts
index 8f227c89..1efe0f55 100644
--- a/packages/sdk/src/build/build-get-collection.test.js
+++ b/packages/sdk/src/build/build-get-collection.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isGetCollection} from "../interaction/interaction"
-import {getCollection} from "./build-get-collection.js"
+import {getCollection} from "./build-get-collection"
 
 describe("Build Get Collection", () => {
   test("Get Collection", async () => {
diff --git a/packages/sdk/src/build/build-get-events-at-block-height-range.test.js b/packages/sdk/src/build/build-get-events-at-block-height-range.test.ts
similarity index 96%
rename from packages/sdk/src/build/build-get-events-at-block-height-range.test.js
rename to packages/sdk/src/build/build-get-events-at-block-height-range.test.ts
index 06a9e0d0..9ce5b008 100644
--- a/packages/sdk/src/build/build-get-events-at-block-height-range.test.js
+++ b/packages/sdk/src/build/build-get-events-at-block-height-range.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isGetEvents} from "../interaction/interaction"
-import {getEventsAtBlockHeightRange} from "./build-get-events-at-block-height-range.js"
+import {getEventsAtBlockHeightRange} from "./build-get-events-at-block-height-range"
 
 describe("Build Get Events At Block Height Range", () => {
   test("Get Events At Block Height Range", async () => {
diff --git a/packages/sdk/src/build/build-get-events-at-block-ids.test.js b/packages/sdk/src/build/build-get-events-at-block-ids.test.ts
similarity index 98%
rename from packages/sdk/src/build/build-get-events-at-block-ids.test.js
rename to packages/sdk/src/build/build-get-events-at-block-ids.test.ts
index 84f07a28..06faeab0 100644
--- a/packages/sdk/src/build/build-get-events-at-block-ids.test.js
+++ b/packages/sdk/src/build/build-get-events-at-block-ids.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isGetEvents} from "../interaction/interaction"
-import {getEventsAtBlockIds} from "./build-get-events-at-block-ids.js"
+import {getEventsAtBlockIds} from "./build-get-events-at-block-ids"
 
 describe("Build Get Events At Block Ids", () => {
   test("Get Events At Block Ids", async () => {
diff --git a/packages/sdk/src/build/build-get-latest-block.test.js b/packages/sdk/src/build/build-get-events.test.ts
similarity index 100%
rename from packages/sdk/src/build/build-get-latest-block.test.js
rename to packages/sdk/src/build/build-get-events.test.ts
diff --git a/packages/sdk/src/build/build-validator.test.js b/packages/sdk/src/build/build-get-latest-block.test.ts
similarity index 100%
rename from packages/sdk/src/build/build-validator.test.js
rename to packages/sdk/src/build/build-get-latest-block.test.ts
diff --git a/packages/sdk/src/build/build-get-network-parameters.test.js b/packages/sdk/src/build/build-get-network-parameters.test.ts
similarity index 98%
rename from packages/sdk/src/build/build-get-network-parameters.test.js
rename to packages/sdk/src/build/build-get-network-parameters.test.ts
index ef46a6ce..86b44210 100644
--- a/packages/sdk/src/build/build-get-network-parameters.test.js
+++ b/packages/sdk/src/build/build-get-network-parameters.test.ts
@@ -2,7 +2,7 @@ import {
   initInteraction,
   isGetNetworkParameters,
 } from "../interaction/interaction"
-import {getNetworkParameters} from "./build-get-network-parameters.js"
+import {getNetworkParameters} from "./build-get-network-parameters"
 
 describe("Build Get Network Parameters", () => {
   test("Get Network Parameters", async () => {
diff --git a/packages/sdk/src/build/build-get-transaction-status.test.js b/packages/sdk/src/build/build-get-transaction-status.test.ts
similarity index 98%
rename from packages/sdk/src/build/build-get-transaction-status.test.js
rename to packages/sdk/src/build/build-get-transaction-status.test.ts
index 75496b8f..b01ccdae 100644
--- a/packages/sdk/src/build/build-get-transaction-status.test.js
+++ b/packages/sdk/src/build/build-get-transaction-status.test.ts
@@ -2,7 +2,7 @@ import {
   initInteraction,
   isGetTransactionStatus,
 } from "../interaction/interaction"
-import {getTransactionStatus} from "./build-get-transaction-status.js"
+import {getTransactionStatus} from "./build-get-transaction-status"
 
 describe("Build Get Transaction Status", () => {
   test("Get Transaction Status", async () => {
diff --git a/packages/sdk/src/build/build-get-transaction.test.js b/packages/sdk/src/build/build-get-transaction.test.ts
similarity index 86%
rename from packages/sdk/src/build/build-get-transaction.test.js
rename to packages/sdk/src/build/build-get-transaction.test.ts
index da9a22e4..a3a5154f 100644
--- a/packages/sdk/src/build/build-get-transaction.test.js
+++ b/packages/sdk/src/build/build-get-transaction.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isGetTransaction} from "../interaction/interaction"
-import {getTransaction} from "./build-get-transaction.js"
+import {getTransaction} from "./build-get-transaction"
 
 describe("Build Get Transaction", () => {
   test("Get Transaction", async () => {
diff --git a/packages/sdk/src/build/build-limit.test.js b/packages/sdk/src/build/build-limit.test.ts
similarity index 87%
rename from packages/sdk/src/build/build-limit.test.js
rename to packages/sdk/src/build/build-limit.test.ts
index 31d60376..de45db03 100644
--- a/packages/sdk/src/build/build-limit.test.js
+++ b/packages/sdk/src/build/build-limit.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction} from "../interaction/interaction"
-import {limit} from "./build-limit.js"
+import {limit} from "./build-limit"
 
 describe("Build Limit", () => {
   test("Build Limit", async () => {
diff --git a/packages/sdk/src/build/build-payer.test.js b/packages/sdk/src/build/build-payer.test.ts
similarity index 82%
rename from packages/sdk/src/build/build-payer.test.js
rename to packages/sdk/src/build/build-payer.test.ts
index a6029532..c7f1df39 100644
--- a/packages/sdk/src/build/build-payer.test.js
+++ b/packages/sdk/src/build/build-payer.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction} from "../interaction/interaction"
-import {payer} from "./build-payer.js"
+import {payer} from "./build-payer"
 
 describe("Build Payer", () => {
   test("Build Payer", async () => {
@@ -7,7 +7,7 @@ describe("Build Payer", () => {
 
     let ix = await (await payer(authz))(initInteraction())
 
-    const payerAccount = ix.accounts[ix.payer]
+    const payerAccount = ix.accounts[ix.payer[0]]
 
     expect(payerAccount.addr).toEqual(authz.addr)
     expect(payerAccount.role).toEqual({
diff --git a/packages/sdk/src/build/build-ping.test.js b/packages/sdk/src/build/build-ping.test.ts
similarity index 85%
rename from packages/sdk/src/build/build-ping.test.js
rename to packages/sdk/src/build/build-ping.test.ts
index 97179a32..0d2edfb6 100644
--- a/packages/sdk/src/build/build-ping.test.js
+++ b/packages/sdk/src/build/build-ping.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isPing} from "../interaction/interaction"
-import {ping} from "./build-ping.js"
+import {ping} from "./build-ping"
 
 describe("Build Ping", () => {
   test("Build Ping", async () => {
diff --git a/packages/sdk/src/build/build-proposer.test.js b/packages/sdk/src/build/build-proposer.test.ts
similarity index 81%
rename from packages/sdk/src/build/build-proposer.test.js
rename to packages/sdk/src/build/build-proposer.test.ts
index 7d1972f3..c67d0ae1 100644
--- a/packages/sdk/src/build/build-proposer.test.js
+++ b/packages/sdk/src/build/build-proposer.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction} from "../interaction/interaction"
-import {proposer} from "./build-proposer.js"
+import {proposer} from "./build-proposer"
 
 describe("Build Proposer", () => {
   test("Build Proposer", async () => {
@@ -7,7 +7,7 @@ describe("Build Proposer", () => {
 
     let ix = await (await proposer(authz))(initInteraction())
 
-    const proposerAccount = ix.accounts[ix.proposer]
+    const proposerAccount = ix.accounts[ix.proposer!]
 
     expect(proposerAccount.addr).toEqual(authz.addr)
     expect(proposerAccount.role).toEqual({
diff --git a/packages/sdk/src/build/build-ref.test.js b/packages/sdk/src/build/build-ref.test.ts
similarity index 88%
rename from packages/sdk/src/build/build-ref.test.js
rename to packages/sdk/src/build/build-ref.test.ts
index 2a691963..73c2717c 100644
--- a/packages/sdk/src/build/build-ref.test.js
+++ b/packages/sdk/src/build/build-ref.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction} from "../interaction/interaction"
-import {ref} from "./build-ref.js"
+import {ref} from "./build-ref"
 
 describe("Build Ref", () => {
   test("Build Ref", async () => {
diff --git a/packages/sdk/src/build/build-script.test.js b/packages/sdk/src/build/build-script.test.ts
similarity index 89%
rename from packages/sdk/src/build/build-script.test.js
rename to packages/sdk/src/build/build-script.test.ts
index fe3c92f6..9217c8a9 100644
--- a/packages/sdk/src/build/build-script.test.js
+++ b/packages/sdk/src/build/build-script.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isScript} from "../interaction/interaction"
-import {script} from "./build-script.js"
+import {script} from "./build-script"
 
 describe("Build Script", () => {
   test("Build Script", async () => {
diff --git a/packages/sdk/src/build/build-transaction.test.js b/packages/sdk/src/build/build-transaction.test.ts
similarity index 88%
rename from packages/sdk/src/build/build-transaction.test.js
rename to packages/sdk/src/build/build-transaction.test.ts
index e64ae28c..26d65e0d 100644
--- a/packages/sdk/src/build/build-transaction.test.js
+++ b/packages/sdk/src/build/build-transaction.test.ts
@@ -1,5 +1,5 @@
 import {initInteraction, isTransaction} from "../interaction/interaction"
-import {transaction} from "./build-transaction.js"
+import {transaction} from "./build-transaction"
 
 describe("Build Transaction", () => {
   test("Build Transaction", async () => {
diff --git a/packages/sdk/src/resolve/resolve-final-normalization.test.js b/packages/sdk/src/build/build-validator.test.ts
similarity index 100%
rename from packages/sdk/src/resolve/resolve-final-normalization.test.js
rename to packages/sdk/src/build/build-validator.test.ts
diff --git a/packages/sdk/src/build/build-voucher-intercept.test.js b/packages/sdk/src/build/build-voucher-intercept.test.ts
similarity index 100%
rename from packages/sdk/src/build/build-voucher-intercept.test.js
rename to packages/sdk/src/build/build-voucher-intercept.test.ts
diff --git a/packages/sdk/src/resolve/resolve-proposer-sequence-number.test.js b/packages/sdk/src/build/build.test.ts
similarity index 100%
rename from packages/sdk/src/resolve/resolve-proposer-sequence-number.test.js
rename to packages/sdk/src/build/build.test.ts
diff --git a/packages/sdk/src/contract.test.js b/packages/sdk/src/contract.test.ts
similarity index 89%
rename from packages/sdk/src/contract.test.js
rename to packages/sdk/src/contract.test.ts
index 40f95cea..9d131e13 100644
--- a/packages/sdk/src/contract.test.js
+++ b/packages/sdk/src/contract.test.ts
@@ -1,13 +1,13 @@
 import * as root from "./sdk"
-import * as decode from "./decode/decode.js"
+import * as decode from "./decode/decode"
 import * as encode from "./encode/encode"
 import * as interaction from "./interaction/interaction"
-import * as send from "./send/send.js"
+import * as send from "./send/send"
 import * as template from "@onflow/util-template"
 
 const interfaceContract =
-  (label, wat) =>
-  ([template]) => {
+  (label: string, wat: any) =>
+  ([template]: TemplateStringsArray): void => {
     const keys = template.replace(/\s+/g, "|").split("|").filter(Boolean)
 
     describe(label, () => {
diff --git a/packages/sdk/src/encode/encode.test.js b/packages/sdk/src/encode/encode.test.ts
similarity index 100%
rename from packages/sdk/src/encode/encode.test.js
rename to packages/sdk/src/encode/encode.test.ts
diff --git a/packages/sdk/src/resolve/resolve-arguments.test.js b/packages/sdk/src/resolve/resolve-arguments.test.ts
similarity index 93%
rename from packages/sdk/src/resolve/resolve-arguments.test.js
rename to packages/sdk/src/resolve/resolve-arguments.test.ts
index ebf30cea..22b02abd 100644
--- a/packages/sdk/src/resolve/resolve-arguments.test.js
+++ b/packages/sdk/src/resolve/resolve-arguments.test.ts
@@ -29,7 +29,7 @@ describe("resolveArguments", () => {
       },
     }
 
-    const res = await resolveArguments(ix)
+    const res = await resolveArguments(ix as any)
     expect(res.arguments[argID].asArgument).toEqual(argObj)
   })
 
@@ -56,7 +56,7 @@ describe("resolveArguments", () => {
       },
     }
 
-    const res = await resolveArguments(ix)
+    const res = await resolveArguments(ix as any)
     expect(res.arguments[argID].resolve).not.toHaveBeenCalled()
     expect(res.arguments[argID].resolveArgument).toHaveBeenCalled()
     expect(res.arguments[argID].asArgument).toEqual(argObj)
@@ -92,7 +92,7 @@ describe("resolveArguments", () => {
       },
     }
 
-    const res = await resolveArguments(ix)
+    const res = await resolveArguments(ix as any)
     expect(res.arguments[argID].resolveArgument).toHaveBeenCalled()
     expect(resolveTwo).toHaveBeenCalled()
     expect(res.arguments[argID].asArgument).toEqual(argObj)
@@ -134,6 +134,6 @@ describe("resolveArguments", () => {
       },
     }
 
-    await expect(resolveArguments(ix)).rejects.toThrow()
+    await expect(resolveArguments(ix as any)).rejects.toThrow()
   })
 })
diff --git a/packages/sdk/src/resolve/resolve-cadence.test.js b/packages/sdk/src/resolve/resolve-cadence.test.ts
similarity index 97%
rename from packages/sdk/src/resolve/resolve-cadence.test.js
rename to packages/sdk/src/resolve/resolve-cadence.test.ts
index 22e9c2ec..c92f3ec9 100644
--- a/packages/sdk/src/resolve/resolve-cadence.test.js
+++ b/packages/sdk/src/resolve/resolve-cadence.test.ts
@@ -4,10 +4,10 @@ import {
   put,
   makeScript,
 } from "../interaction/interaction"
-import {resolveCadence} from "./resolve-cadence.js"
+import {resolveCadence} from "./resolve-cadence"
 import {config} from "@onflow/config"
 
-const idle = () => new Promise(resolve => setTimeout(resolve), 0)
+const idle = () => new Promise(resolve => setTimeout(resolve, 0))
 
 describe("resolveCadence", () => {
   describe("0xHelloWorld-style account identifier syntax", () => {
diff --git a/packages/sdk/src/resolve/resolve-compute-limit.test.js b/packages/sdk/src/resolve/resolve-compute-limit.test.ts
similarity index 95%
rename from packages/sdk/src/resolve/resolve-compute-limit.test.js
rename to packages/sdk/src/resolve/resolve-compute-limit.test.ts
index 74cde6d8..3dd5febc 100644
--- a/packages/sdk/src/resolve/resolve-compute-limit.test.js
+++ b/packages/sdk/src/resolve/resolve-compute-limit.test.ts
@@ -4,7 +4,7 @@ import {
   makeTransaction,
 } from "../interaction/interaction"
 import {config} from "@onflow/config"
-import {resolveComputeLimit} from "./resolve-compute-limit.js"
+import {resolveComputeLimit} from "./resolve-compute-limit"
 
 describe("resolveComputeLimit", () => {
   test("transaction compute limit has priority", async () => {
diff --git a/packages/sdk/src/resolve/resolve-validators.test.js b/packages/sdk/src/resolve/resolve-final-normalization.test.ts
similarity index 100%
rename from packages/sdk/src/resolve/resolve-validators.test.js
rename to packages/sdk/src/resolve/resolve-final-normalization.test.ts
diff --git a/packages/sdk/src/resolve/resolve-ref-block-id.test.js b/packages/sdk/src/resolve/resolve-ref-block-id.test.ts
similarity index 100%
rename from packages/sdk/src/resolve/resolve-ref-block-id.test.js
rename to packages/sdk/src/resolve/resolve-ref-block-id.test.ts
diff --git a/packages/sdk/src/resolve/resolve-signatures.test.js b/packages/sdk/src/resolve/resolve-signatures.test.ts
similarity index 85%
rename from packages/sdk/src/resolve/resolve-signatures.test.js
rename to packages/sdk/src/resolve/resolve-signatures.test.ts
index 074c03d7..654c50d8 100644
--- a/packages/sdk/src/resolve/resolve-signatures.test.js
+++ b/packages/sdk/src/resolve/resolve-signatures.test.ts
@@ -9,6 +9,7 @@ import {
   limit,
   authorizations,
 } from "../sdk"
+import {InteractionResolverKind, InteractionTag} from "@onflow/typedefs"
 
 const signingFunction = jest.fn(() => ({
   addr: "foo",
@@ -17,20 +18,20 @@ const signingFunction = jest.fn(() => ({
 }))
 
 const TRANSACTION = {
-  tag: "TRANSACTION",
+  tag: InteractionTag.TRANSACTION,
   message: {
     cadence: "",
     refBlock: "123",
     computeLimit: 156,
-    proposer: null,
-    payer: null,
+    proposer: "",
+    payer: "",
     authorizations: [],
     params: [],
     arguments: [],
   },
   accounts: {
     foo: {
-      kind: "ACCOUNT",
+      kind: InteractionResolverKind.ACCOUNT,
       tempId: "foo",
       addr: "foo",
       keyId: 1,
@@ -39,12 +40,13 @@ const TRANSACTION = {
       signingFunction: signingFunction,
       resolve: null,
       role: {proposer: false, authorizer: false, payer: true, param: false},
+      authorization: () => {},
     },
   },
   proposer: "foo",
   authorizations: ["foo"],
-  payer: "foo",
-}
+  payer: ["foo"],
+} as any
 
 test("exports function", () => {
   expect(typeof resolveSignatures).toBe("function")
@@ -73,7 +75,7 @@ test("voucher in signable", async () => {
     ])
   )
 
-  const signable = buildSignable(ix.accounts[ix.proposer], {}, ix)
+  const signable = buildSignable(ix.accounts[ix.proposer!], {} as any, ix)
 
   expect(signable.voucher).toEqual({
     cadence: "",
diff --git a/packages/sdk/src/resolve/resolve-voucher-intercept.test.js b/packages/sdk/src/resolve/resolve-voucher-intercept.test.ts
similarity index 76%
rename from packages/sdk/src/resolve/resolve-voucher-intercept.test.js
rename to packages/sdk/src/resolve/resolve-voucher-intercept.test.ts
index c1852f1f..1292db8f 100644
--- a/packages/sdk/src/resolve/resolve-voucher-intercept.test.js
+++ b/packages/sdk/src/resolve/resolve-voucher-intercept.test.ts
@@ -1,4 +1,5 @@
-import {resolveVoucherIntercept} from "./resolve-voucher-intercept.js"
+import {InteractionResolverKind, InteractionTag} from "@onflow/typedefs"
+import {resolveVoucherIntercept} from "./resolve-voucher-intercept"
 
 test("exports function", () => {
   expect(typeof resolveVoucherIntercept).toBe("function")
@@ -7,13 +8,13 @@ test("exports function", () => {
 test("voucherIntercept is executed", async () => {
   let executed = false
 
-  const checkFunc = async voucher => {
+  const checkFunc = async (voucher: any) => {
     executed = true
     expect(typeof voucher).toBe("object")
   }
 
   const ix = {
-    tag: "TRANSACTION",
+    tag: InteractionTag.TRANSACTION,
     assigns: {
       "ix.voucher-intercept": checkFunc,
     },
@@ -21,15 +22,15 @@ test("voucherIntercept is executed", async () => {
       cadence: "",
       refBlock: "123",
       computeLimit: 156,
-      proposer: null,
-      payer: null,
+      proposer: "",
+      payer: "",
       authorizations: [],
       params: [],
       arguments: [],
     },
     accounts: {
       foo: {
-        kind: "ACCOUNT",
+        kind: InteractionResolverKind.ACCOUNT,
         tempId: "foo",
         addr: "foo",
         keyId: 1,
@@ -38,12 +39,13 @@ test("voucherIntercept is executed", async () => {
         signingFunction: () => ({signature: "123"}),
         resolve: null,
         role: {proposer: false, authorizer: false, payer: true, param: false},
+        authorization: () => {},
       },
     },
     proposer: "foo",
     authorizations: ["foo"],
-    payer: "foo",
-  }
+    payer: ["foo"],
+  } as any
 
   await resolveVoucherIntercept(ix)
 
@@ -53,13 +55,13 @@ test("voucherIntercept is executed", async () => {
 test("voucherIntercept throws error", async () => {
   let executed = false
 
-  const checkFuncThrowError = async voucher => {
+  const checkFuncThrowError = async (voucher: any) => {
     executed = true
     throw new Error("test error")
   }
 
   const ix = {
-    tag: "TRANSACTION",
+    tag: InteractionTag.TRANSACTION,
     assigns: {
       "ix.voucher-intercept": checkFuncThrowError,
     },
@@ -67,15 +69,15 @@ test("voucherIntercept throws error", async () => {
       cadence: "",
       refBlock: "123",
       computeLimit: 156,
-      proposer: null,
-      payer: null,
+      proposer: "",
+      payer: "",
       authorizations: [],
       params: [],
       arguments: [],
     },
     accounts: {
       foo: {
-        kind: "ACCOUNT",
+        kind: InteractionResolverKind.ACCOUNT,
         tempId: "foo",
         addr: "foo",
         keyId: 1,
@@ -84,12 +86,13 @@ test("voucherIntercept throws error", async () => {
         signingFunction: () => ({signature: "123"}),
         resolve: null,
         role: {proposer: false, authorizer: false, payer: true, param: false},
+        authorization: () => {},
       },
     },
     proposer: "foo",
     authorizations: ["foo"],
-    payer: "foo",
-  }
+    payer: ["foo"],
+  } as any
 
   await expect(resolveVoucherIntercept(ix)).rejects.toThrow()
 
diff --git a/packages/sdk/src/send/send.test.js b/packages/sdk/src/send/send.test.ts
similarity index 100%
rename from packages/sdk/src/send/send.test.js
rename to packages/sdk/src/send/send.test.ts
diff --git a/packages/sdk/src/wallet-utils/encode-signable.test.js b/packages/sdk/src/wallet-utils/encode-signable.test.ts
similarity index 98%
rename from packages/sdk/src/wallet-utils/encode-signable.test.js
rename to packages/sdk/src/wallet-utils/encode-signable.test.ts
index f6d88aa4..c8c1c807 100644
--- a/packages/sdk/src/wallet-utils/encode-signable.test.js
+++ b/packages/sdk/src/wallet-utils/encode-signable.test.ts
@@ -1,7 +1,7 @@
 import {
   encodeMessageFromSignable,
   UnableToDetermineMessageEncodingTypeForSignerAddress,
-} from "./encode-signable.js"
+} from "./encode-signable"
 import {
   encodeTransactionPayload as encodeInsideMessage,
   encodeTransactionEnvelope as encodeOutsideMessage,
diff --git a/packages/sdk/src/wallet-utils/validate-tx.test.js b/packages/sdk/src/wallet-utils/validate-tx.test.ts
similarity index 97%
rename from packages/sdk/src/wallet-utils/validate-tx.test.js
rename to packages/sdk/src/wallet-utils/validate-tx.test.ts
index b0ae56c2..3cae2d50 100644
--- a/packages/sdk/src/wallet-utils/validate-tx.test.js
+++ b/packages/sdk/src/wallet-utils/validate-tx.test.ts
@@ -1,4 +1,4 @@
-import {validateSignableTransaction} from "./"
+import {validateSignableTransaction} from "."
 import {
   encodeTransactionPayload as encodeInsideMessage,
   encodeTransactionEnvelope as encodeOutsideMessage,