diff --git a/pages/framework/card-sdk.mdx b/pages/framework/card-sdk.mdx
index 9eb418c..5163d27 100644
--- a/pages/framework/card-sdk.mdx
+++ b/pages/framework/card-sdk.mdx
@@ -1,13 +1,309 @@
# Card SDK
The Card SDK provides the glue between the Javascript defined in the TokenScript project and the engine.
-It is essentially a 2-way message bus that allows the TokenScript developer to make requests to the engine and to receive updated data.
+It is essentially a 2-way message bus that allows the TokenScript developer to make requests to the engine and to receive updated data and other events emitted by the engine.
It also allows the user to access various data including context data, environment variables & contract information.
## Token Context Data
+As explained in the introduction to TokenScript attributes, Token Context data is made available through the card SDK.
+Our starter templates already handles the dataChange event which is used to provide initial and updated token context data to your card.
+
+If you want to register your own listener, you can do so by overwriting the following eventHandler
+
+```typescript
+tokenscript.tokens.dataChanged = async (oldTokens: any, updatedTokens: ITokenData, id: string) => {
+
+}
+```
+
+For our Svelte & React templates, the `updatedTokens.currentInstance` is automatically written to a global context variable that your UI can react to.
+
## Environment Variables
+To access environment variables within your card, ensure that the variables is added into `ts:meta` as demonstrated [here](./tokenscript-syntax/xml).
+
+You can then access these variables via the `tokenscript.env` object:
+
+```typescript
+tokenscript.env.MY_ENV_VARIABLE
+```
+
+## Event handlers
+
+The engine include event handler infrastructure that allows the registration of multiple event listeners throughout your application.
+
+Currently, there is only one handler however more will be added in the future:
+
+- TRANSACTION_EVENT
+
+```typescript
+// Types
+interface TokenScriptEvents {
+ TRANSACTION_EVENT: ITransactionStatus
+}
+
+// Usage
+tokenscript.on("TRANSACTION_EVENT", (data: ITransactionStatus) => {
+ // Handle transaction event
+})
+```
+
+The TRANSACTION_EVENT can be used to react to transaction status even when the default action button is used to trigger the transaction.
+
+## Bundled libraries
+
+To reduce the size of built TokenScripts, some common libraries are bundled with the Card SDK.
+This allows the use of these libraries without explicitly installing them via NPM.
+
+Bundled libraries
+
+- Ethers.js ^v6.13 - available via the `ethers` global variable
+
## Engine & UX actions
+### setProps
+
+One of the most important engine actions is `setProps`. It allows the user to define values that can be used as inputs to attributes & transactions:
+
+```typescript
+tokenscript.action.setProps({
+ myAttribute: "123",
+ myAttribute2: 456
+})
+```
+
+When invoking this method, the engine checks these values to see if they are `ts:user-entry` attributes.
+If they are not user entry values the engine checks if any of these values are a dependency for another attribute defined in the current scope.
+If so the engine will reload those attributes and return the updated data to the card via the `dataChanged` handler explained above.
+In this way, attribute values can be updated automatically based on an input that is set programmatically from within the card.
+
+Likewise, declarative transactions can reference these values as transactions arguments.
+
+Both attributes & transactions reference these values using the `local-ref` XML attribute:
+
+```xml
+
+
+
+
+
+```
+
+### show/hideLoader
+
+A self-explanatory method, this allows the user to show or hide the default card loaded provided the TokenScript viewer UI:
+
+`tokenscript.action.showLoader()` OR `tokenscript.action.hideLoader()`.
+
+### setActionButton
+
+The setActionButton method allows the developer to control the state of the default action button:
+
+```typescript
+// Type
+type setActionButton = (options: { show?: boolean, disable?: boolean, text?: string }) => void
+
+// Usage
+tokenscript.action.setActionButton({
+ show: true, // Whether to show the button
+ disable: false, // Whether to make the button disabled
+ text: "Transfer Now" // The text of the button
+})
+```
+
+This allows the user to hide, disable or update the button text based on some conditions defined in Javascript.
+
+### executeTransaction
+
+`executeTransaction` is used to invoke declarative transactions programmatically as discussed in [TokenScript Transactions](./tokenscript-syntax/transactions).
+
+```typescript
+// Types
+interface TXOptions {
+ txName?: string
+}
+
+interface ITransactionStatus {
+ status: 'started'|'aborted'|'submitted'|'confirmed'|'completed',
+ txNumber?: string,
+ txLink?: string,
+ txRecord?: any
+}
+
+interface ITransactionListener {
+ (data: ITransactionStatus): void|Promise
+}
+
+type ExecuteTransaction = (optionsOrTxName?: string|TXOptions, listener?: ITransactionListener) => Promise
+
+// Usage
+
+// 1. Execute the default transaction (specified in `ts:card`)
+if (!await tokenscript.action.executeTransaction()){
+ return; // User aborted transaction
+}
+// Do some post-transaction processing
+
+// 2. Execute a top-level named transaction, with some input values from Javascript
+tokenscript.action.setProps({
+ secretCode: "1234"
+});
+if (!await tokenscript.action.executeTransaction("levelUp")){
+ return; // User aborted transaction
+}
+
+// 3. Use a transaction progress listener
+await tokenscript.action.executeTransaction("levelUp", (txInfo) => {
+ // Update UI based on transaction process
+});
+
+```
+
+Since the executeTransaction method is async, it can be used to chain together transactions and other off-chain processes.
+
+### showMessageToast
+
+This allows the developer to show message notifications using the toast notification system provided by TokenScript viewer.
+Along with the other UI specific methods, this helps keep the user-experience consistent across all TokenScript applications.
+
+```typescript
+// Type
+type ShowMessageToast = (type: 'success'|'info'|'warning'|'error', title: string, description: string) => void;
+
+// Usage
+tokenscript.action.showMessageToast("error", "An error occurred", "Detailed information about the error");
+```
+
+### showTransactionToast
+
+Like the previous method, this allows the user to show transaction specific notifications:
+
+```typescript
+// Type
+type ShowTransactionToast = (status: "submitted"|"confirmed", chain: number, txHash: string) => void;
+
+// Usage
+tokenscript.action.showTransactionToast('confirmed', 137, "0x05b9d22ce9ac87e399c18c488c3e02327945ffb4633890030789ea1f2f783e0b");
+```
+
+Note: This method only needs to be used when using the injected ethereum provider. If you are using declarative transactions, notifications are already taken care of by the engine.
+
+### closeCard
+
+This method simply closes the current card:
+
+```typescript
+tokenscript.action.closeCard();
+```
+
+### openCard
+
+You can also switch between cards using the `openCard` method.
+
+```typescript
+// Type
+type OpenCard = (name: string, originId?: string, tokenId?: string) => void;
+
+// Usage
+tokenscript.action.openCard({
+ name: "myCardName",
+ originId: "ReallyCoolToken", // This is the name of the origin contract as defined in the tokenscript.xml.
+ tokenId: "1" // The tokenId we want to open the card for
+});
+```
+
+If originId or tokenId are not provided, the current token context is used to open the new card.
+
## Ethereum methods
+
+### Signing
+
+You can request the user to sign a personal message like this:
+
+```typescript
+// Type
+type SignPersonal = (msgParams: {data: string|Uint8Array}, callback?: (error: any, data: string) => void) => void|Promise;
+
+// Usage
+const signature = await tokenscript.personal.sign({data: "My message"});
+```
+
+This method is async but can also take a callback as well.
+
+**Note: If you need typed data signing, use the Ethereum Provider**
+
+### getRpcUrls
+
+The `getRpcUrls` method provides an array of RPC URLs for the specified chain ID:
+
+```typescript
+// Type
+type GetRpcUrls = (chain: number) => string[];
+
+// Usage
+const rpcUrls = tokenscript.eth.getRpcUrls(137);
+````
+
+These URLs are configured and provided by the TokenScript Engine.
+
+### getRpcProvider
+
+Instead of requesting URLs and configuring the ethereum provider yourself, you can get an ethers.js provider directly:
+
+```typescript
+// Type
+type GetRpcProvider = (chain: number) => AbstractProvider; // ethers.AbstractProvider
+
+// Usage
+const provider = tokenscript.eth.getRpcProvider(137);
+```
+
+If more than one RPC URL is defined for the specified chain ethers.FallbackProvider is returned, otherwise ethers.JsonRpcProvider is returned.
+
+### getContractInfo
+
+It's often helpful to get contract information based on the name specified in the TokenScript XML.
+In this way there is no need to hard-code contract addresses and ABI JSON within your Javascript code.
+Instead, this config information can be specified within the `tokenscript-project.json` environment variables and made available via this API method.
+
+```typescript
+// Type
+type GetContractInfo = (name: string, chain?: number) => {chain: number, address: string, abi: any};
+
+// Usage
+const contractInfo = tokenscript.eth.getContractInfo("MyReallyCoolToken");
+```
+
+If the chain parameter isn't provided, the chain of the current token is used or the first chain specified within `ts:contract`.
+
+### getContractInstance
+
+Just like getContractInfo, we can get an ethers.Contract instance based on the name & chain provided.
+These contracts must have an ABI specified within `ts:contract` for the methods you want to execute.
+
+```typescript
+// Type
+type GetContractInstance = (name: string, chain?: number) => Contract; // ethers.Contract
+
+// Usage
+const contract = tokenscript.eth.getContractInstance("MyReallyCoolToken"); // ABI with getTokenPoints is defined in `ts:contract`
+const points = await contract.getTokenPoints(token.tokenId);
+```
+
+This is most helpful when we want to read contract data within a card, without the use of TokenScript attributes that are loaded when the card is open.
+
+## Ethereum provider
+
+To allow scenarios that are not supported by TokenScript's declarative transactions, the Card SDK provides an EIP-1193 proxy.
+This is the standard injected provider (`window.ethereum`) that you would be familiar with from integrating with Metamask and other browser extension wallets.
+
+To use this provider, it's recommended that you wrap it with Ethers.js BrowserProvider like so:
+```typescript
+const provider = new ethers.BrowserProvider(window.ethereum);
+
+// You can then get an ethers contract instance to interact with a contract
+const contract = new ethers.Contract(contractAddress, abi, provider);
+```
+
+**Note: When using the injected provider, you must take care of chain switching, transaction notifications & error handling yourself.**
\ No newline at end of file
diff --git a/pages/framework/tokenscript-syntax/transactions.mdx b/pages/framework/tokenscript-syntax/transactions.mdx
index 951fa5a..29e50e2 100644
--- a/pages/framework/tokenscript-syntax/transactions.mdx
+++ b/pages/framework/tokenscript-syntax/transactions.mdx
@@ -107,7 +107,7 @@ If the card does not contain a transaction, the `window.onConfirm` function is t
An example of this would be if an API call or Ethereum signature is needed to get some transaction inputs.
In this case we can perform my transaction prep and execute the transaction programmatically:
-```javascript
+```typescript
window.onConfirn = async () => {
const res = await getApiData(); // Get some off-chain data to use in our transaction
tokenscript.action.setProps({myAttribute: res.myAttribute});
@@ -122,4 +122,9 @@ In this way, even the default action button can be used to chain transactions to
Sometimes a single action button isn't enough, so transactions can be invoked programmatically using the Card SDK.
See the [Card SDK documentation](../card-sdk) for more details.
-When the default action button isn't needed, it can be disabled. See [here](./cards#uiButton) for further details.
\ No newline at end of file
+When the default action button isn't needed, it can be disabled. See [here](./cards#uiButton) for further details.
+
+## Ethereum provider
+
+To allow scenarios that are not supported by TokenScript's declarative transactions, the Card SDK provides a EIP-1193 proxy.
+Learn how to use it [here](../card-sdk#ethereum-provider).
\ No newline at end of file