Options
All
  • Public
  • Public/Protected
  • All
Menu

Module awcp/awcp

The idea here is to use TypeScript's type system to express the shape of messages (really events) passed between the Aepp and the Waellet. The Aepp is what you are writing, and the Waellet is what sidekick talks to.

It might be useful to reference:

The message protocol works by both the Aepp and the Waellet posting events into the window's global event queue.

From sidekick's perspective, there are 4 "parameters" in such a message

  1. Whether the message is for the Aepp or for the Waellet
  2. Whether the message is a request or a response
  3. The method of the message (a string)
  4. The actual data contained in the message. For "requests" this parameter is called params, and for "responses" this parameter is called result. The nomenclature of the compound types reflects this.

Remember that types are fake. There is nothing crazy going on here. All we are doing is using weird looking notation to express in a very straightforward manner how the data you have to deal with is going to be shaped.

From your perspective as a developer using sidekick in your application, you will probably never deal with the "request" types, only with the "result" types that top-level functions might return.

We will work outside-in. If we combine the first two parameters, there are 4 possible types of messages:

  1. An Aepp-to-Waellet request. This is the generic type Window_A2W_Requ
  2. A Waellet-to-Aepp response. This is the generic type Window_W2A_Resp
  3. A Waellet-to-Aepp request. This is the generic type Window_W2A_Requ
  4. An Aepp-to-Waellet response. This does not occur in practice.

A "generic type" is a function at the level of types. Meaning it is a transformation that takes one or more types as inputs (in our case, two, for the two remaining parameters), and produces a single type as an output.

Here are the types:

export type Window_A2W_Requ<method_s, params_t> =
{type : "to_waellet",
data : RpcRequ<method_s, params_t>};

export type Window_W2A_Resp<method_s, result_t> =
{type : "to_aepp",
data : RpcResp<method_s, result_t>};

export type Window_W2A_Requ<method_s, params_t> =
{type : "to_aepp",
data : RpcRequ<method_s, params_t>};

The method_s is meant to be a string, which corresponds to the third parameter listed above. Remember that in TypeScript, literal values are valid types. The params_t or result_t is meant to be a type, which corresponds to the actual meat of the message, the fourth parameter listed above.

For example, let's look at the messages sent between the Aepp and the Waellet when you send the Waellet a transaction that you want the Waellet to sign, but not propagate into the network.

// This is the data (4th parameter) that your Skylight sends to
// the Waellet whenever you ask the Waellet to sign a transaction.
//
// Note: the `returnSigned` attribute in this object determines
// whether or not the Waellet attempts to propagate the
// transaction after signing it. The fact that we can use literal
// values in types allows us to express the distinct behaviors
// within the type system, and to catch potential crossups at
// compile time.
export type AWCP_A2W_params_transaction_sign_no_propagate =
{tx : string,
returnSigned : true,
networkId : string};

// This is the data (4th parameter) that the wallet sends back
// after signing the transaction.
//
// This is what will be returned back to you in a top-level
// function call.
export type AWCP_W2A_result_transaction_sign_no_propagate =
{signedTransaction: string};

// This is the shape of data that Skylight actually posts in the
// window event queue
export type AWCP_A2W_requ_transaction_sign_no_propagate =
Window_A2W_Requ<"transaction.sign",
AWCP_A2W_params_transaction_sign_no_propagate>;

// This is the shape of data that the Waellet posts in the window
// event queue in response
export type AWCP_W2A_resp_transaction_sign_no_propagate =
Window_W2A_Resp<"transaction.sign",
AWCP_W2A_result_transaction_sign_no_propagate>;

This module uses types to define the expected behavior of the waellet. There are no functions here. Specifically, this module defines an interface called AWCP_Waellet, which is implemented by the MsgR class.

The idea there is for Skylight to treat the waellet like a black box. You send it one of the request types, it sends you back the corresponding response type. How it goes about doing that is George's problem.

The exception to this idiom is the manner in which the Waellet announces that it exists

Index

Type aliases

AWCP_A2W_params_address_subscribe: { type: "subscribe"; value: "connected" }

address.subscribe messages

Type declaration

  • type: "subscribe"
  • value: "connected"
AWCP_A2W_params_connection_open: { name: string; networkId?: string; version: number }

connection.open aepp-to-waellet message parameters

NOTE(dak): networkId appears by experimentation to be optional. This may be a source of bugs in the future if it turns out to not be optional

Type declaration

  • name: string
  • Optional networkId?: string
  • version: number
AWCP_A2W_params_transaction_sign_no_propagate: { networkId: string; returnSigned: true; tx: string }

Type declaration

  • networkId: string
  • returnSigned: true
  • tx: string
AWCP_A2W_params_transaction_sign_yes_propagate: { networkId: string; returnSigned: false; tx: string }

Type declaration

  • networkId: string
  • returnSigned: false
  • tx: string
AWCP_A2W_requ_address_subscribe: Window_A2W_Requ<"address.subscribe", AWCP_A2W_params_address_subscribe>
AWCP_A2W_requ_connection_open: Window_A2W_Requ<"connection.open", AWCP_A2W_params_connection_open>
AWCP_A2W_requ_transaction_sign_no_propagate: Window_A2W_Requ<"transaction.sign", AWCP_A2W_params_transaction_sign_no_propagate>
AWCP_A2W_requ_transaction_sign_yes_propagate: Window_A2W_Requ<"transaction.sign", AWCP_A2W_params_transaction_sign_yes_propagate>
AWCP_W2A_params_connection_announcePresence: { id: string; name: string; origin: string; type: "window" | "extension" }

Type declaration

  • id: string
  • name: string
  • origin: string
  • type: "window" | "extension"
AWCP_W2A_requ_connection_announcePresence: Window_W2A_Requ<"connection.announcePresence", AWCP_W2A_params_connection_announcePresence>
AWCP_W2A_resp_address_subscribe: Window_W2A_Resp<"address.subscribe", AWCP_W2A_result_address_subscribe>
AWCP_W2A_resp_connection_open: Window_W2A_Resp<"connection.open", AWCP_W2A_result_connection_open>
AWCP_W2A_resp_transaction_sign_no_propagate: Window_W2A_Resp<"transaction.sign", AWCP_W2A_result_transaction_sign_no_propagate>
AWCP_W2A_resp_transaction_sign_yes_propagate: Window_W2A_Resp<"transaction.sign", AWCP_W2A_result_transaction_sign_yes_propagate>
AWCP_W2A_result_address_subscribe: { address: { connected: object; current: object }; subscription: string[] }

Type declaration

  • address: { connected: object; current: object }
    • connected: object
    • current: object
  • subscription: string[]
AWCP_W2A_result_connection_open: AWCP_W2A_params_connection_announcePresence

connection.open wallet-to-aepp result happens to be the same data we get spammed with for connection.announcePresence

AWCP_W2A_result_transaction_sign_no_propagate: { signedTransaction: string }

this is when returnSigned: true the server or sidekick attempts to propagate the transaction

Type declaration

  • signedTransaction: string
AWCP_W2A_result_transaction_sign_yes_propagate: { transactionHash: { blockHash: string; blockHeight: number; hash: string; rawTx: string; signatures: string[]; tx: { amount: number; fee: number; nonce: number; payload: string; recipientId: string; senderId: string; type: string; version: number } } }

this is when returnSigned: false the wallet attempts to propagate the transaction

Type declaration

  • transactionHash: { blockHash: string; blockHeight: number; hash: string; rawTx: string; signatures: string[]; tx: { amount: number; fee: number; nonce: number; payload: string; recipientId: string; senderId: string; type: string; version: number } }
    • blockHash: string
    • blockHeight: number
    • hash: string
    • rawTx: string
    • signatures: string[]
    • tx: { amount: number; fee: number; nonce: number; payload: string; recipientId: string; senderId: string; type: string; version: number }
      • amount: number
      • fee: number
      • nonce: number
      • payload: string
      • recipientId: string
      • senderId: string
      • type: string
      • version: number
RpcRequ<method_s, params_t>: { id: number; jsonrpc: "2.0"; method: method_s; params: params_t }

RPC request type

Type parameters

  • method_s

  • params_t

Type declaration

  • id: number
  • jsonrpc: "2.0"
  • method: method_s
  • params: params_t
RpcResp<method_s, result_t>: { id: number; jsonrpc: "2.0"; method: method_s; result: result_t }

RPC respsonse type

Strictly speaking, this violates the JSON RPC 2.0 spec, because the "method" field is not required. However, it is present in practice so /shrug/

Type parameters

  • method_s

  • result_t

Type declaration

  • id: number
  • jsonrpc: "2.0"
  • method: method_s
  • result: result_t
Window_A2W_Requ<method_s, params_t>: { data: RpcRequ<method_s, params_t>; type: "to_waellet" }

aepp-to-waellet request

Type parameters

  • method_s

  • params_t

Type declaration

  • data: RpcRequ<method_s, params_t>
  • type: "to_waellet"
Window_W2A_Requ<method_s, params_t>: { data: RpcRequ<method_s, params_t>; type: "to_aepp" }

waellet-to-aepp request (ONLY used for connection.announcePresence)

Type parameters

  • method_s

  • params_t

Type declaration

  • data: RpcRequ<method_s, params_t>
  • type: "to_aepp"
Window_W2A_Resp<method_s, result_t>: { data: RpcResp<method_s, result_t>; type: "to_aepp" }

waellet-to-aepp response:

Type parameters

  • method_s

  • result_t

Type declaration

  • data: RpcResp<method_s, result_t>
  • type: "to_aepp"

Generated using TypeDoc