@rango-dev/wallets-core 0.62.1 → 0.62.2-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/namespaces/tron/actions.d.ts +18 -0
- package/dist/namespaces/tron/actions.d.ts.map +1 -1
- package/dist/namespaces/tron/builders.d.ts +3 -0
- package/dist/namespaces/tron/builders.d.ts.map +1 -1
- package/dist/namespaces/tron/constants.d.ts +12 -0
- package/dist/namespaces/tron/constants.d.ts.map +1 -1
- package/dist/namespaces/tron/mod.js +1 -1
- package/dist/namespaces/tron/mod.js.map +4 -4
- package/dist/namespaces/tron/types.d.ts +148 -1
- package/dist/namespaces/tron/types.d.ts.map +1 -1
- package/dist/namespaces/tron/utils.d.ts +20 -0
- package/dist/namespaces/tron/utils.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/namespaces/tron/actions.ts +103 -0
- package/src/namespaces/tron/builders.ts +11 -0
- package/src/namespaces/tron/constants.ts +15 -0
- package/src/namespaces/tron/types.ts +168 -2
- package/src/namespaces/tron/utils.ts +75 -1
|
@@ -1,2 +1,20 @@
|
|
|
1
|
+
import type { ProviderAPI, TronActions } from './types.js';
|
|
2
|
+
import type { Context } from '../../hub/namespaces/mod.js';
|
|
3
|
+
import type { FunctionWithContext } from '../../types/actions.js';
|
|
1
4
|
export declare const recommended: (readonly ["disconnect", typeof import("../common/actions.js").disconnect])[];
|
|
5
|
+
/**
|
|
6
|
+
* Reads a TRC-20 `allowance(owner, spender)` via a constant contract call and
|
|
7
|
+
* returns it as a decimal string.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getAllowance(instance: () => ProviderAPI | undefined): FunctionWithContext<TronActions['getAllowance'], Context>;
|
|
10
|
+
/**
|
|
11
|
+
* Builds (via the node) a ready-to-sign `approve(spender, amount)` transaction
|
|
12
|
+
* on the TRC-20 token contract.
|
|
13
|
+
*
|
|
14
|
+
* The transaction carries TronWeb's default 60s expiration, which is the same
|
|
15
|
+
* window server-built approvals use.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildApproveTransaction(instance: () => ProviderAPI | undefined): FunctionWithContext<TronActions['buildApproveTransaction'], Context>;
|
|
18
|
+
/** Reads a transaction's on-chain info (empty while the tx is unconfirmed). */
|
|
19
|
+
export declare function getTransactionInfo(instance: () => ProviderAPI | undefined): FunctionWithContext<TronActions['getTransactionInfo'], Context>;
|
|
2
20
|
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/actions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAclE,eAAO,MAAM,WAAW,+EAAyB,CAAC;AAElD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,WAAW,GAAG,SAAS,GACtC,mBAAmB,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,CAyB3D;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,WAAW,GAAG,SAAS,GACtC,mBAAmB,CAAC,WAAW,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC,CAkCtE;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,WAAW,GAAG,SAAS,GACtC,mBAAmB,CAAC,WAAW,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,CAMjE"}
|
|
@@ -2,4 +2,7 @@ import type { TronActions } from './types.js';
|
|
|
2
2
|
import { ActionBuilder } from '../../mod.js';
|
|
3
3
|
export declare const connect: () => ActionBuilder<TronActions, "connect">;
|
|
4
4
|
export declare const canEagerConnect: () => ActionBuilder<TronActions, "canEagerConnect">;
|
|
5
|
+
export declare const getAllowance: () => ActionBuilder<TronActions, "getAllowance">;
|
|
6
|
+
export declare const buildApproveTransaction: () => ActionBuilder<TronActions, "buildApproveTransaction">;
|
|
7
|
+
export declare const getTransactionInfo: () => ActionBuilder<TronActions, "getTransactionInfo">;
|
|
5
8
|
//# sourceMappingURL=builders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/builders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK7C,eAAO,MAAM,OAAO,6CAIc,CAAC;AAEnC,eAAO,MAAM,eAAe,qDAC0C,CAAC"}
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/builders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK7C,eAAO,MAAM,OAAO,6CAIc,CAAC;AAEnC,eAAO,MAAM,eAAe,qDAC0C,CAAC;AAEvE,eAAO,MAAM,YAAY,kDACuC,CAAC;AAEjE,eAAO,MAAM,uBAAuB,6DAGjC,CAAC;AAEJ,eAAO,MAAM,kBAAkB,wDAC6C,CAAC"}
|
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
export declare const CAIP_NAMESPACE = "tron";
|
|
2
2
|
export declare const CAIP_TRON_CHAIN_ID = "tron";
|
|
3
|
+
/**
|
|
4
|
+
* Default fee limit (in SUN) for a client-built TRC-20 approve transaction.
|
|
5
|
+
* 250 TRX — matches the value the backend used for server-built approvals.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_APPROVE_FEE_LIMIT = 250000000;
|
|
8
|
+
/** The TRC-20 call the approve prerequisite issues. */
|
|
9
|
+
export declare const APPROVE_FUNCTION_SELECTOR = "approve(address,uint256)";
|
|
10
|
+
/**
|
|
11
|
+
* Length in hex characters of the function selector that prefixes a call's
|
|
12
|
+
* data: 4 bytes, two characters each.
|
|
13
|
+
*/
|
|
14
|
+
export declare const FUNCTION_SELECTOR_HEX_LENGTH = 8;
|
|
3
15
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/constants.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,kBAAkB,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/constants.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,kBAAkB,SAAS,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,YAAc,CAAC;AAErD,uDAAuD;AACvD,eAAO,MAAM,yBAAyB,6BAA6B,CAAC;AAEpE;;;GAGG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var N=Object.defineProperty;var e=(o,t)=>N(o,"name",{value:t,configurable:!0});var a=(o,t)=>{for(var r in t)N(o,r,{get:t[r],enumerable:!0})};var O={};a(O,{buildApproveTransaction:()=>q,getAllowance:()=>X,getTransactionInfo:()=>Q,recommended:()=>G});function I(o){let[,t]=o.state();t("network",null),t("accounts",null),t("connected",!1),t("connecting",!1),t("connectArgs",null)}e(I,"disconnect");var k=[["disconnect",I]];var f="tron",S="tron";var l="approve(address,uint256)";var R={};a(R,{buildApprovePayload:()=>A,formatAccountsToCAIP:()=>Y,getTronWeb:()=>c,hexAddressToTronBase58:()=>i,isTronNamespace:()=>_});import{getNamespaceFromCaip2ChainId as U}from"@hub3js/std/utils";import{AccountId as B}from"caip";function _(o){return U(o)===f}e(_,"isTronNamespace");function A(o,t){let n=o.raw_data?.contract?.[0]?.parameter?.value;if(!(!n?.data||!n.owner_address||!n.contract_address))return{type:"WEB",owner_address:n.owner_address,call_value:0,contract_address:n.contract_address,fee_limit:t,function_selector:l,parameter:n.data.slice(8),chainType:null}}e(A,"buildApprovePayload");function c(o){let t=o();if(!t?.tronWeb)throw new Error("Tron is not available on your wallet.");return t.tronWeb}e(c,"getTronWeb");var $="41";function i(o,t){let r=$+t.replace(/^0x/,"");return o.address.fromHex(r)}e(i,"hexAddressToTronBase58");function Y(o){return o.map(t=>B.format({address:t.toString(),chainId:{namespace:f,reference:S}}))}e(Y,"formatAccountsToCAIP");var G=[...k];function X(o){return async(t,r)=>{let n=c(o),p=i(n,r.owner),x=i(n,r.token),g=i(n,r.spender),{result:u,constant_result:m}=await n.transactionBuilder.triggerConstantContract(x,"allowance(address,address)",{},[{type:"address",value:p},{type:"address",value:g}],p);if(!u?.result||!m?.length)throw new Error("Failed to read the TRC-20 allowance.");return BigInt(`0x${m[0]}`).toString()}}e(X,"getAllowance");function q(o){return async(t,r)=>{let n=c(o),p=i(n,r.owner),x=i(n,r.token),g=i(n,r.spender),u=r.feeLimit??25e7,{result:m,transaction:T}=await n.transactionBuilder.triggerSmartContract(x,l,{feeLimit:u},[{type:"address",value:g},{type:"uint256",value:r.amount}],p);if(!m?.result)throw new Error("Failed to build the TRC-20 approve transaction.");return{...T,__payload__:A(T,u)}}}e(q,"buildApproveTransaction");function Q(o){return async(t,r)=>c(o).trx.getUnconfirmedTransactionInfo(r)}e(Q,"getTransactionInfo");var F={};a(F,{recommended:()=>Z});function h(o){let[,t]=o.state();t("connecting",!1)}e(h,"intoConnectionFinished");var b=[["connect",h]];var Z=[...b];var W={};a(W,{recommended:()=>ie});import{createStore as St}from"zustand/vanilla";import{produce as nt}from"immer";import{produce as pt}from"immer";var s=class{static{e(this,"ActionBuilder")}name;#e=new Map;#t=new Map;#o=new Map;#r=new Map;#n;constructor(t){this.name=t}and(t){return this.#e.has(this.name)||this.#e.set(this.name,[]),this.#e.get(this.name)?.push(t),this}or(t){return this.#t.has(this.name)||this.#t.set(this.name,[]),this.#t.get(this.name)?.push(t),this}before(t){return this.#r.has(this.name)||this.#r.set(this.name,[]),this.#r.get(this.name)?.push(t),this}after(t){return this.#o.has(this.name)||this.#o.set(this.name,[]),this.#o.get(this.name)?.push(t),this}action(t){return this.#n=t,this}build(){if(!this.#n)throw new Error("Your action builder should includes an action.");return{actionName:this.name,action:this.#n,before:this.#r,after:this.#o,and:this.#e,or:this.#t}}};import*as Qt from"caip";import{AccountId as se}from"caip";function D(o){try{return se.parse(o),!0}catch{return!1}}e(D,"isValidCaipAddress");function d(o,t){if(!t.every(D))throw new Error(`Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${t}`);let[,r]=o.state();return r("accounts",t),r("connected",!0),t}e(d,"connectAndUpdateStateForSingleNetwork");function y(o){let[,t]=o.state();t("connecting",!0)}e(y,"intoConnecting");var w=[["connect",y]];var ie=[["connect",d]];var V={};a(V,{recommended:()=>ae});var ae=[...w];var M={};a(M,{buildApproveTransaction:()=>ue,canEagerConnect:()=>de,connect:()=>ce,getAllowance:()=>pe,getTransactionInfo:()=>me});var ce=e(()=>new s("connect").and(d).before(y).after(h),"connect"),de=e(()=>new s("canEagerConnect"),"canEagerConnect"),pe=e(()=>new s("getAllowance"),"getAllowance"),ue=e(()=>new s("buildApproveTransaction"),"buildApproveTransaction"),me=e(()=>new s("getTransactionInfo"),"getTransactionInfo");export{f as CAIP_NAMESPACE,S as CAIP_TRON_CHAIN_ID,O as actions,F as after,W as and,V as before,M as builders,_ as isTronNamespace,R as utils};
|
|
2
2
|
//# sourceMappingURL=mod.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/namespaces/tron/actions.ts", "../../../src/namespaces/common/actions.ts", "../../../src/namespaces/tron/after.ts", "../../../src/namespaces/common/after.ts", "../../../src/namespaces/tron/and.ts", "../../../src/hub/store/store.ts", "../../../src/hub/store/namespaces.ts", "../../../src/hub/store/providers.ts", "../../../src/builders/action.ts", "../../../src/utils/mod.ts", "../../../src/namespaces/common/helpers.ts", "../../../src/namespaces/common/and.ts", "../../../src/namespaces/common/before.ts", "../../../src/namespaces/tron/before.ts", "../../../src/namespaces/tron/builders.ts"
|
|
4
|
-
"sourcesContent": ["import { recommended as commonRecommended } from '../common/actions.js';\n\nexport const recommended = [...commonRecommended];\n", "import type { Context } from '../../hub/namespaces/mod.js';\n\nexport function disconnect(context: Context): void {\n const [, setState] = context.state();\n setState('network', null);\n setState('accounts', null);\n setState('connected', false);\n setState('connecting', false);\n setState('connectArgs', null);\n}\n\nexport const recommended = [['disconnect', disconnect] as const];\n", "import { recommended as commonRecommended } from '../common/after.js';\n\nexport const recommended = [...commonRecommended];\n", "import type { Context } from '../../hub/namespaces/mod.js';\n\nexport function intoConnectionFinished(context: Context) {\n const [, setState] = context.state();\n setState('connecting', false);\n}\n\nexport const recommended = [['connect', intoConnectionFinished] as const];\n", "import { connectAndUpdateStateForSingleNetwork } from '../common/mod.js';\n\nexport const recommended = [\n ['connect', connectAndUpdateStateForSingleNetwork] as const,\n];\n", "import type { StoreApi } from 'zustand/vanilla';\n\nimport { createStore as createZustandStore } from 'zustand/vanilla';\n\nimport { extend, type Store } from './extend.js';\nimport { hubStore, type HubStore } from './hub.js';\nimport { namespacesStore, type NamespaceStore } from './namespaces.js';\nimport { providersStore, type ProviderStore } from './providers.js';\n\n/************ State ************/\n\nexport interface State {\n hub: HubStore;\n providers: ProviderStore;\n namespaces: NamespaceStore;\n}\n\nexport type RawStore = StoreApi<State>;\n\nexport const createStore = (): Store => {\n const store = createZustandStore<State>((...api) => {\n return {\n hub: hubStore(...api),\n providers: providersStore(...api),\n namespaces: namespacesStore(...api),\n };\n });\n\n return extend(store);\n};\n", "/************ Namespace ************/\n\nimport type { StateCreator } from 'zustand';\n\nimport { produce } from 'immer';\n\nimport {\n ConsumableEvents,\n type NamespaceConnectedEvent,\n type NamespaceDisconnectedEvent,\n type NamespaceSwitchedAccountEvent,\n type NamespaceSwitchedNetworkEvent,\n} from './events.js';\nimport { namespaceStateSelector, type State } from './mod.js';\n\n// Currently, namespace doesn't has any config.\nexport type NamespaceConfig = object;\n\nexport interface NamespaceData {\n accounts: null | string[];\n network: null | string;\n connected: boolean;\n connecting: boolean;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n connectArgs: Record<string, any> | null;\n}\n\ninterface NamespaceInfo {\n providerId: string;\n namespaceId: string;\n}\n\ninterface NamespaceItem {\n info: NamespaceInfo;\n data: NamespaceData;\n error: unknown;\n}\n\ntype NamespaceState = {\n events: InstanceType<typeof ConsumableEvents>;\n list: Record<string, NamespaceItem>;\n};\n\ninterface NamespaceActions {\n addNamespace: (id: string, config: NamespaceInfo) => void;\n updateStatus: <K extends keyof NamespaceData>(\n id: string,\n key: K,\n value: NamespaceData[K]\n ) => void;\n\n _produceEventsWhenUpdatingStatus: <K extends keyof NamespaceData>(\n namespace: NamespaceItem,\n id: string,\n key: K,\n value: NamespaceData[K]\n ) => void;\n}\ninterface NamespaceSelectors {\n getNamespaceData(storeId: string): NamespaceData;\n}\n\nexport type NamespaceStore = NamespaceState &\n NamespaceActions &\n NamespaceSelectors;\ntype NamespaceStateCreator = StateCreator<State, [], [], NamespaceStore>;\n\nconst namespacesStore: NamespaceStateCreator = (set, get) => ({\n events: new ConsumableEvents(),\n\n list: {},\n addNamespace: (id, info) => {\n const data: NamespaceData = {\n accounts: null,\n network: null,\n connected: false,\n connecting: false,\n connectArgs: null,\n };\n\n const item = {\n data,\n error: '',\n info,\n };\n\n set(\n produce((state: State) => {\n state.namespaces.list[id] = item;\n })\n );\n },\n updateStatus: (id, key, value) => {\n const ns = get().namespaces.list[id];\n if (!ns) {\n throw new Error(`No namespace with '${id}' found.`);\n }\n\n get().namespaces._produceEventsWhenUpdatingStatus(ns, id, key, value);\n\n // Updating state\n set(\n produce((state: State) => {\n state.namespaces.list[id].data[key] = value;\n })\n );\n },\n getNamespaceData(storeId) {\n return namespaceStateSelector(get(), storeId);\n },\n\n _produceEventsWhenUpdatingStatus: (namespace, id, key, value) => {\n if (key === 'accounts') {\n // check for both null and empty array\n const isAccountsEmpty =\n Object.is(value, null) || (Array.isArray(value) && value.length === 0);\n\n if (isAccountsEmpty) {\n const currentConnectedStatus = get().namespaces.list[id].data.connected;\n if (currentConnectedStatus) {\n const event: NamespaceDisconnectedEvent = {\n type: 'namespace_disconnected',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n };\n\n get().namespaces.events.push(event);\n }\n // Skip emitting disconnect event, if the `connected` is false\n } else {\n const currentAccounts = get().namespaces.list[id].data.accounts;\n\n if (!currentAccounts) {\n const event: NamespaceConnectedEvent = {\n type: 'namespace_connected',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n accounts: value as string[],\n };\n\n get().namespaces.events.push(event);\n } else {\n const areSameAccounts =\n // Clone the object from the Zustand store, as it's immutable, to avoid errors during sorting.\n [...currentAccounts].sort().toString() ===\n (value as string[]).sort().toString();\n\n if (!areSameAccounts) {\n const event: NamespaceSwitchedAccountEvent = {\n type: 'namespace_account_switched',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n previousAccounts: currentAccounts,\n accounts: value as string[],\n };\n\n get().namespaces.events.push(event);\n }\n }\n }\n } else if (key === 'network') {\n const currentNetwork = get().namespaces.list[id].data.network;\n\n const event: NamespaceSwitchedNetworkEvent = {\n type: 'namespace_network_switched',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n network: value as string,\n previousNetwork: currentNetwork,\n };\n\n get().namespaces.events.push(event);\n }\n },\n});\n\nexport { namespacesStore };\n", "import type { Namespace } from '../../namespaces/common/types.js';\nimport type { State as InternalProviderState } from '../provider/mod.js';\nimport type { SignerFactory } from 'rango-types';\nimport type { StateCreator } from 'zustand';\n\nimport { produce } from 'immer';\n\nimport { ConsumableEvents, type ProviderDetectedEvent } from './events.js';\nimport { guessProviderStateSelector, type State } from './mod.js';\n\ntype Browsers = 'firefox' | 'chrome' | 'edge' | 'brave' | 'homepage';\ntype Property<N extends string, V> = { name: N; value: V };\n\ntype NamespacesProperty = Property<\n 'namespaces',\n {\n selection: 'single' | 'multiple';\n data: {\n label: string;\n id: string;\n value: Namespace;\n unsupported?: boolean;\n isChainSupported: (chain: string) => boolean;\n }[];\n }\n>;\ntype DerivationPathProperty = Property<\n 'derivationPath',\n {\n data: {\n id: string;\n label: string;\n namespace: Namespace;\n generateDerivationPath: (index: string) => string;\n }[];\n }\n>;\ntype DetailsProperty = Property<\n 'details',\n {\n mobileWallet?: boolean;\n showOnMobile?: boolean;\n isContractWallet?: boolean;\n }\n>;\ntype SignersProperty = Property<\n 'signers',\n {\n getSigners: () => Promise<SignerFactory>;\n }\n>;\n\nexport type ProviderMetadata = {\n name: string;\n icon: string;\n extensions: Partial<Record<Browsers, string>>;\n properties?: Array<\n | NamespacesProperty\n | DerivationPathProperty\n | DetailsProperty\n | SignersProperty\n >;\n};\n\nexport interface ProviderConfig {\n metadata: ProviderMetadata;\n}\n\nexport type ProviderInfo = ProviderConfig;\n\ninterface ProviderData {\n installed: boolean;\n}\n\ninterface ProviderItem {\n config: ProviderConfig;\n data: ProviderData;\n error: unknown;\n}\n\ntype ProviderState = {\n events: ConsumableEvents;\n list: Record<string, ProviderItem>;\n};\ninterface ProviderActions {\n addProvider: (id: string, config: ProviderConfig) => void;\n removeProvider: (id: string) => void;\n updateStatus: <K extends keyof ProviderData>(\n id: string,\n key: K,\n value: ProviderData[K]\n ) => void;\n\n _produceEventsWhenUpdatingStatus: <K extends keyof ProviderData>(\n provider: ProviderItem,\n id: string,\n key: K,\n value: ProviderData[K]\n ) => void;\n}\n\ninterface ProviderSelectors {\n /**\n * Provider has a limited state to itself, to be compatible with legacy, we try to produce same object as legacy\n * which includes namespace state as well.\n */\n guessNamespacesState: (id: string) => InternalProviderState;\n}\n\nexport type ProviderStore = ProviderState & ProviderActions & ProviderSelectors;\ntype ProvidersStateCreator = StateCreator<State, [], [], ProviderStore>;\n\nconst providersStore: ProvidersStateCreator = (set, get) => ({\n events: new ConsumableEvents(),\n\n list: {},\n addProvider: (id, config) => {\n const item = {\n data: {\n installed: false,\n },\n error: '',\n config,\n };\n\n set(\n produce((state: State) => {\n state.providers.list[id] = item;\n })\n );\n },\n removeProvider: (id) => {\n set(\n produce((state: State) => {\n delete state.providers.list[id];\n })\n );\n },\n updateStatus: (id, key, value) => {\n const provider = get().providers.list[id];\n if (!provider) {\n throw new Error(`No namespace namespace with '${id}' found.`);\n }\n\n get().providers._produceEventsWhenUpdatingStatus(provider, id, key, value);\n\n set(\n produce((state: State) => {\n state.providers.list[id].data[key] = value;\n })\n );\n },\n guessNamespacesState: (providerId: string): InternalProviderState => {\n return guessProviderStateSelector(get(), providerId);\n },\n\n _produceEventsWhenUpdatingStatus: (_provider, id, key, _value) => {\n if (key === 'installed') {\n const event: ProviderDetectedEvent = {\n type: 'provider_detected',\n provider: id,\n };\n\n get().providers.events.push(event);\n }\n },\n});\n\nexport { providersStore };\n", "import type { Actions, Context, Operators } from '../hub/namespaces/types.js';\nimport type { AnyFunction, FunctionWithContext } from '../types/actions.js';\n\nexport interface ActionByBuilder<T, Context> {\n actionName: keyof T;\n and: Operators<T>;\n or: Operators<T>;\n after: Operators<T>;\n before: Operators<T>;\n action: FunctionWithContext<T[keyof T], Context>;\n}\n\n/*\n * TODO:\n * Currently, to use this builder you will write something like this:\n * new ActionBuilder<EvmActions, 'disconnect'>('disconnect').after(....)\n *\n * I couldn't figure it out to be able typescript infer the constructor value as key of actions.\n * Ideal usage:\n * new ActionBuilder<EvmActions>('disconnect').after(....)\n *\n */\nexport class ActionBuilder<T extends Actions<T>, K extends keyof T> {\n readonly name: K;\n #and: Operators<T> = new Map();\n #or: Operators<T> = new Map();\n #after: Operators<T> = new Map();\n #before: Operators<T> = new Map();\n #action: FunctionWithContext<T[keyof T], Context<T>> | undefined;\n\n constructor(name: K) {\n this.name = name;\n }\n\n public and(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#and.has(this.name)) {\n this.#and.set(this.name, []);\n }\n this.#and.get(this.name)?.push(action);\n return this;\n }\n\n public or(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#or.has(this.name)) {\n this.#or.set(this.name, []);\n }\n this.#or.get(this.name)?.push(action);\n return this;\n }\n\n public before(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#before.has(this.name)) {\n this.#before.set(this.name, []);\n }\n this.#before.get(this.name)?.push(action);\n return this;\n }\n\n public after(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#after.has(this.name)) {\n this.#after.set(this.name, []);\n }\n this.#after.get(this.name)?.push(action);\n return this;\n }\n\n public action(action: FunctionWithContext<T[keyof T], Context<T>>) {\n this.#action = action;\n return this;\n }\n\n public build(): ActionByBuilder<T, Context<T>> {\n if (!this.#action) {\n throw new Error('Your action builder should includes an action.');\n }\n\n return {\n actionName: this.name,\n action: this.#action,\n before: this.#before,\n after: this.#after,\n and: this.#and,\n or: this.#or,\n };\n }\n}\n", "/*\n * It is not a good idea to re-export all of CAIP because if they have a breaking change, we will break as well.\n * It would be better to create an abstraction over them and export our own interface to ensure it is under our control.\n */\nexport * as CAIP from 'caip';\n\nexport { generateStoreId } from '../hub/helpers.js';\nexport * from './versions.js';\n", "import { AccountId } from 'caip';\n\nexport function isValidCaipAddress(address: string): boolean {\n try {\n AccountId.parse(address);\n return true;\n } catch {\n return false;\n }\n}\n", "import type {\n Accounts,\n AccountsWithActiveChain,\n} from './../../types/accounts.js';\nimport type { Context } from '../../hub/namespaces/mod.js';\n\nimport { isValidCaipAddress } from './helpers.js';\n\nexport function connectAndUpdateStateForSingleNetwork(\n context: Context,\n accounts: Accounts\n) {\n if (!accounts.every(isValidCaipAddress)) {\n throw new Error(\n `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts}`\n );\n }\n\n const [, setState] = context.state();\n setState('accounts', accounts);\n setState('connected', true);\n return accounts;\n}\n\nexport function connectAndUpdateStateForMultiNetworks(\n context: Context,\n accounts: AccountsWithActiveChain\n) {\n if (!accounts.accounts.every(isValidCaipAddress)) {\n throw new Error(\n `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts.accounts}`\n );\n }\n\n const [, setState] = context.state();\n setState('accounts', accounts.accounts);\n setState('network', accounts.network);\n setState('connected', true);\n return accounts;\n}\n\nexport const recommended = [];\n", "import type { Context } from '../../hub/namespaces/mod.js';\n\nexport function intoConnecting(context: Context) {\n const [, setState] = context.state();\n setState('connecting', true);\n}\n\n// Please consider if you are going to add something here, make sure it works on all namespaces.\nexport const recommended = [['connect', intoConnecting] as const];\n", "import { recommended as commonRecommended } from '../common/before.js';\n\nexport const recommended = [...commonRecommended];\n", "import type { TronActions } from './types.js';\n\nimport { ActionBuilder } from '../../mod.js';\nimport { intoConnectionFinished } from '../common/after.js';\nimport { connectAndUpdateStateForSingleNetwork } from '../common/and.js';\nimport { intoConnecting } from '../common/before.js';\n\nexport const connect = () =>\n new ActionBuilder<TronActions, 'connect'>('connect')\n .and(connectAndUpdateStateForSingleNetwork)\n .before(intoConnecting)\n .after(intoConnectionFinished);\n\nexport const canEagerConnect = () =>\n new ActionBuilder<TronActions, 'canEagerConnect'>('canEagerConnect');\n", "import type { CaipAccount } from '../common/mod.js';\n\nimport { getNamespaceFromCaip2ChainId } from '@hub3js/std/utils';\nimport { AccountId } from 'caip';\n\nimport { CAIP_NAMESPACE, CAIP_TRON_CHAIN_ID } from './constants.js';\n\nexport function isTronNamespace(caip2ChainId: string): boolean {\n return getNamespaceFromCaip2ChainId(caip2ChainId) === CAIP_NAMESPACE;\n}\n\nexport function formatAccountsToCAIP(accounts: string[]) {\n return accounts.map(\n (account) =>\n AccountId.format({\n address: account.toString(),\n chainId: {\n namespace: CAIP_NAMESPACE,\n reference: CAIP_TRON_CHAIN_ID,\n },\n }) as CaipAccount\n );\n}\n", "/*\n * TODO: I couldn't found tron in caip\n * @see https://namespaces.chainagnostic.org/\n */\n\n// if the value needs to be change make sure you will update mapCaipNamespaceToLegacyNetworkName as well\nexport const CAIP_NAMESPACE = 'tron';\nexport const CAIP_TRON_CHAIN_ID = 'tron';\n"],
|
|
5
|
-
"mappings": "6IAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,
|
|
6
|
-
"names": ["actions_exports", "__export", "recommended", "disconnect", "context", "setState", "__name", "recommended", "
|
|
3
|
+
"sources": ["../../../src/namespaces/tron/actions.ts", "../../../src/namespaces/common/actions.ts", "../../../src/namespaces/tron/constants.ts", "../../../src/namespaces/tron/utils.ts", "../../../src/namespaces/tron/after.ts", "../../../src/namespaces/common/after.ts", "../../../src/namespaces/tron/and.ts", "../../../src/hub/store/store.ts", "../../../src/hub/store/namespaces.ts", "../../../src/hub/store/providers.ts", "../../../src/builders/action.ts", "../../../src/utils/mod.ts", "../../../src/namespaces/common/helpers.ts", "../../../src/namespaces/common/and.ts", "../../../src/namespaces/common/before.ts", "../../../src/namespaces/tron/before.ts", "../../../src/namespaces/tron/builders.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ProviderAPI, TronActions } from './types.js';\nimport type { Context } from '../../hub/namespaces/mod.js';\nimport type { FunctionWithContext } from '../../types/actions.js';\n\nimport { recommended as commonRecommended } from '../common/actions.js';\n\nimport {\n APPROVE_FUNCTION_SELECTOR,\n DEFAULT_APPROVE_FEE_LIMIT,\n} from './constants.js';\nimport {\n buildApprovePayload,\n getTronWeb,\n hexAddressToTronBase58,\n} from './utils.js';\n\nexport const recommended = [...commonRecommended];\n\n/**\n * Reads a TRC-20 `allowance(owner, spender)` via a constant contract call and\n * returns it as a decimal string.\n */\nexport function getAllowance(\n instance: () => ProviderAPI | undefined\n): FunctionWithContext<TronActions['getAllowance'], Context> {\n return async (_context, params) => {\n const tronWeb = getTronWeb(instance);\n const owner = hexAddressToTronBase58(tronWeb, params.owner);\n const token = hexAddressToTronBase58(tronWeb, params.token);\n const spender = hexAddressToTronBase58(tronWeb, params.spender);\n\n const { result, constant_result } =\n await tronWeb.transactionBuilder.triggerConstantContract(\n token,\n 'allowance(address,address)',\n {},\n [\n { type: 'address', value: owner },\n { type: 'address', value: spender },\n ],\n owner\n );\n\n if (!result?.result || !constant_result?.length) {\n throw new Error('Failed to read the TRC-20 allowance.');\n }\n\n return BigInt(`0x${constant_result[0]}`).toString();\n };\n}\n\n/**\n * Builds (via the node) a ready-to-sign `approve(spender, amount)` transaction\n * on the TRC-20 token contract.\n *\n * The transaction carries TronWeb's default 60s expiration, which is the same\n * window server-built approvals use.\n */\nexport function buildApproveTransaction(\n instance: () => ProviderAPI | undefined\n): FunctionWithContext<TronActions['buildApproveTransaction'], Context> {\n return async (_context, params) => {\n const tronWeb = getTronWeb(instance);\n const owner = hexAddressToTronBase58(tronWeb, params.owner);\n const token = hexAddressToTronBase58(tronWeb, params.token);\n const spender = hexAddressToTronBase58(tronWeb, params.spender);\n\n const feeLimit = params.feeLimit ?? DEFAULT_APPROVE_FEE_LIMIT;\n const { result, transaction } =\n await tronWeb.transactionBuilder.triggerSmartContract(\n token,\n APPROVE_FUNCTION_SELECTOR,\n { feeLimit },\n [\n { type: 'address', value: spender },\n { type: 'uint256', value: params.amount },\n ],\n owner\n );\n\n if (!result?.result) {\n throw new Error('Failed to build the TRC-20 approve transaction.');\n }\n\n /*\n * `transactionBuilder` returns only the consensus fields. A server-built\n * transaction also carries `__payload__`, which wallets use to re-issue the\n * call when the user edits the allowance, so add it here too.\n */\n return {\n ...transaction,\n __payload__: buildApprovePayload(transaction, feeLimit),\n };\n };\n}\n\n/** Reads a transaction's on-chain info (empty while the tx is unconfirmed). */\nexport function getTransactionInfo(\n instance: () => ProviderAPI | undefined\n): FunctionWithContext<TronActions['getTransactionInfo'], Context> {\n return async (_context, txID) => {\n const tronWeb = getTronWeb(instance);\n // Full node (not solidity), so the info is available right after inclusion.\n return tronWeb.trx.getUnconfirmedTransactionInfo(txID);\n };\n}\n", "import type { Context } from '../../hub/namespaces/mod.js';\n\nexport function disconnect(context: Context): void {\n const [, setState] = context.state();\n setState('network', null);\n setState('accounts', null);\n setState('connected', false);\n setState('connecting', false);\n setState('connectArgs', null);\n}\n\nexport const recommended = [['disconnect', disconnect] as const];\n", "/*\n * TODO: I couldn't found tron in caip\n * @see https://namespaces.chainagnostic.org/\n */\n\n// if the value needs to be change make sure you will update mapCaipNamespaceToLegacyNetworkName as well\nexport const CAIP_NAMESPACE = 'tron';\nexport const CAIP_TRON_CHAIN_ID = 'tron';\n\n/**\n * Default fee limit (in SUN) for a client-built TRC-20 approve transaction.\n * 250 TRX \u2014 matches the value the backend used for server-built approvals.\n */\nexport const DEFAULT_APPROVE_FEE_LIMIT = 250_000_000;\n\n/** The TRC-20 call the approve prerequisite issues. */\nexport const APPROVE_FUNCTION_SELECTOR = 'approve(address,uint256)';\n\n/**\n * Length in hex characters of the function selector that prefixes a call's\n * data: 4 bytes, two characters each.\n */\nexport const FUNCTION_SELECTOR_HEX_LENGTH = 8;\n", "import type {\n ProviderAPI,\n TronBuiltTransaction,\n TronRawDataContract,\n TronTransactionPayload,\n TronWebApi,\n} from './types.js';\nimport type { CaipAccount } from '../common/mod.js';\n\nimport { getNamespaceFromCaip2ChainId } from '@hub3js/std/utils';\nimport { AccountId } from 'caip';\n\nimport {\n APPROVE_FUNCTION_SELECTOR,\n CAIP_NAMESPACE,\n CAIP_TRON_CHAIN_ID,\n FUNCTION_SELECTOR_HEX_LENGTH,\n} from './constants.js';\n\nexport function isTronNamespace(caip2ChainId: string): boolean {\n return getNamespaceFromCaip2ChainId(caip2ChainId) === CAIP_NAMESPACE;\n}\n\n/**\n * Describes a built approve call the way a server-built transaction does.\n *\n * Wallets that let the user choose the allowance rebuild the transaction from\n * `__payload__` instead of decoding `raw_data`. TronWeb's `transactionBuilder`\n * leaves it out, and given an empty one TronLink cannot re-issue the call and\n * reports \"Modification failed\", so the approve can never be signed there.\n *\n * The values are read back out of the built transaction rather than recomputed,\n * so they cannot drift from what was actually built and signed.\n */\nexport function buildApprovePayload(\n transaction: TronBuiltTransaction,\n feeLimit: number\n): TronTransactionPayload | undefined {\n const rawData = transaction.raw_data as\n | { contract?: TronRawDataContract[] }\n | undefined;\n const call = rawData?.contract?.[0]?.parameter?.value;\n\n if (!call?.data || !call.owner_address || !call.contract_address) {\n return undefined;\n }\n\n return {\n type: 'WEB',\n owner_address: call.owner_address,\n call_value: 0,\n contract_address: call.contract_address,\n fee_limit: feeLimit,\n function_selector: APPROVE_FUNCTION_SELECTOR,\n parameter: call.data.slice(FUNCTION_SELECTOR_HEX_LENGTH),\n chainType: null,\n };\n}\n\n/** The wallet-injected TronWeb instance, or a readable error when absent. */\nexport function getTronWeb(\n instance: () => ProviderAPI | undefined\n): TronWebApi {\n const tronInstance = instance();\n if (!tronInstance?.tronWeb) {\n throw new Error('Tron is not available on your wallet.');\n }\n return tronInstance.tronWeb;\n}\n\n/** Tron mainnet address prefix byte (0x41) in hex. */\nconst TRON_HEX_ADDRESS_PREFIX = '41';\n\n/**\n * Prerequisite addresses arrive in 0x-hex (EVM-style) form; TronWeb expects a\n * Tron address. Convert `0x<20-bytes>` \u2192 `41<20-bytes>` \u2192 Base58.\n */\nexport function hexAddressToTronBase58(\n tronWeb: TronWebApi,\n address: string\n): string {\n const tronHex = TRON_HEX_ADDRESS_PREFIX + address.replace(/^0x/, '');\n return tronWeb.address.fromHex(tronHex);\n}\n\nexport function formatAccountsToCAIP(accounts: string[]) {\n return accounts.map(\n (account) =>\n AccountId.format({\n address: account.toString(),\n chainId: {\n namespace: CAIP_NAMESPACE,\n reference: CAIP_TRON_CHAIN_ID,\n },\n }) as CaipAccount\n );\n}\n", "import { recommended as commonRecommended } from '../common/after.js';\n\nexport const recommended = [...commonRecommended];\n", "import type { Context } from '../../hub/namespaces/mod.js';\n\nexport function intoConnectionFinished(context: Context) {\n const [, setState] = context.state();\n setState('connecting', false);\n}\n\nexport const recommended = [['connect', intoConnectionFinished] as const];\n", "import { connectAndUpdateStateForSingleNetwork } from '../common/mod.js';\n\nexport const recommended = [\n ['connect', connectAndUpdateStateForSingleNetwork] as const,\n];\n", "import type { StoreApi } from 'zustand/vanilla';\n\nimport { createStore as createZustandStore } from 'zustand/vanilla';\n\nimport { extend, type Store } from './extend.js';\nimport { hubStore, type HubStore } from './hub.js';\nimport { namespacesStore, type NamespaceStore } from './namespaces.js';\nimport { providersStore, type ProviderStore } from './providers.js';\n\n/************ State ************/\n\nexport interface State {\n hub: HubStore;\n providers: ProviderStore;\n namespaces: NamespaceStore;\n}\n\nexport type RawStore = StoreApi<State>;\n\nexport const createStore = (): Store => {\n const store = createZustandStore<State>((...api) => {\n return {\n hub: hubStore(...api),\n providers: providersStore(...api),\n namespaces: namespacesStore(...api),\n };\n });\n\n return extend(store);\n};\n", "/************ Namespace ************/\n\nimport type { StateCreator } from 'zustand';\n\nimport { produce } from 'immer';\n\nimport {\n ConsumableEvents,\n type NamespaceConnectedEvent,\n type NamespaceDisconnectedEvent,\n type NamespaceSwitchedAccountEvent,\n type NamespaceSwitchedNetworkEvent,\n} from './events.js';\nimport { namespaceStateSelector, type State } from './mod.js';\n\n// Currently, namespace doesn't has any config.\nexport type NamespaceConfig = object;\n\nexport interface NamespaceData {\n accounts: null | string[];\n network: null | string;\n connected: boolean;\n connecting: boolean;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n connectArgs: Record<string, any> | null;\n}\n\ninterface NamespaceInfo {\n providerId: string;\n namespaceId: string;\n}\n\ninterface NamespaceItem {\n info: NamespaceInfo;\n data: NamespaceData;\n error: unknown;\n}\n\ntype NamespaceState = {\n events: InstanceType<typeof ConsumableEvents>;\n list: Record<string, NamespaceItem>;\n};\n\ninterface NamespaceActions {\n addNamespace: (id: string, config: NamespaceInfo) => void;\n updateStatus: <K extends keyof NamespaceData>(\n id: string,\n key: K,\n value: NamespaceData[K]\n ) => void;\n\n _produceEventsWhenUpdatingStatus: <K extends keyof NamespaceData>(\n namespace: NamespaceItem,\n id: string,\n key: K,\n value: NamespaceData[K]\n ) => void;\n}\ninterface NamespaceSelectors {\n getNamespaceData(storeId: string): NamespaceData;\n}\n\nexport type NamespaceStore = NamespaceState &\n NamespaceActions &\n NamespaceSelectors;\ntype NamespaceStateCreator = StateCreator<State, [], [], NamespaceStore>;\n\nconst namespacesStore: NamespaceStateCreator = (set, get) => ({\n events: new ConsumableEvents(),\n\n list: {},\n addNamespace: (id, info) => {\n const data: NamespaceData = {\n accounts: null,\n network: null,\n connected: false,\n connecting: false,\n connectArgs: null,\n };\n\n const item = {\n data,\n error: '',\n info,\n };\n\n set(\n produce((state: State) => {\n state.namespaces.list[id] = item;\n })\n );\n },\n updateStatus: (id, key, value) => {\n const ns = get().namespaces.list[id];\n if (!ns) {\n throw new Error(`No namespace with '${id}' found.`);\n }\n\n get().namespaces._produceEventsWhenUpdatingStatus(ns, id, key, value);\n\n // Updating state\n set(\n produce((state: State) => {\n state.namespaces.list[id].data[key] = value;\n })\n );\n },\n getNamespaceData(storeId) {\n return namespaceStateSelector(get(), storeId);\n },\n\n _produceEventsWhenUpdatingStatus: (namespace, id, key, value) => {\n if (key === 'accounts') {\n // check for both null and empty array\n const isAccountsEmpty =\n Object.is(value, null) || (Array.isArray(value) && value.length === 0);\n\n if (isAccountsEmpty) {\n const currentConnectedStatus = get().namespaces.list[id].data.connected;\n if (currentConnectedStatus) {\n const event: NamespaceDisconnectedEvent = {\n type: 'namespace_disconnected',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n };\n\n get().namespaces.events.push(event);\n }\n // Skip emitting disconnect event, if the `connected` is false\n } else {\n const currentAccounts = get().namespaces.list[id].data.accounts;\n\n if (!currentAccounts) {\n const event: NamespaceConnectedEvent = {\n type: 'namespace_connected',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n accounts: value as string[],\n };\n\n get().namespaces.events.push(event);\n } else {\n const areSameAccounts =\n // Clone the object from the Zustand store, as it's immutable, to avoid errors during sorting.\n [...currentAccounts].sort().toString() ===\n (value as string[]).sort().toString();\n\n if (!areSameAccounts) {\n const event: NamespaceSwitchedAccountEvent = {\n type: 'namespace_account_switched',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n previousAccounts: currentAccounts,\n accounts: value as string[],\n };\n\n get().namespaces.events.push(event);\n }\n }\n }\n } else if (key === 'network') {\n const currentNetwork = get().namespaces.list[id].data.network;\n\n const event: NamespaceSwitchedNetworkEvent = {\n type: 'namespace_network_switched',\n provider: namespace.info.providerId,\n namespace: namespace.info.namespaceId,\n network: value as string,\n previousNetwork: currentNetwork,\n };\n\n get().namespaces.events.push(event);\n }\n },\n});\n\nexport { namespacesStore };\n", "import type { Namespace } from '../../namespaces/common/types.js';\nimport type { State as InternalProviderState } from '../provider/mod.js';\nimport type { SignerFactory } from 'rango-types';\nimport type { StateCreator } from 'zustand';\n\nimport { produce } from 'immer';\n\nimport { ConsumableEvents, type ProviderDetectedEvent } from './events.js';\nimport { guessProviderStateSelector, type State } from './mod.js';\n\ntype Browsers = 'firefox' | 'chrome' | 'edge' | 'brave' | 'homepage';\ntype Property<N extends string, V> = { name: N; value: V };\n\ntype NamespacesProperty = Property<\n 'namespaces',\n {\n selection: 'single' | 'multiple';\n data: {\n label: string;\n id: string;\n value: Namespace;\n unsupported?: boolean;\n isChainSupported: (chain: string) => boolean;\n }[];\n }\n>;\ntype DerivationPathProperty = Property<\n 'derivationPath',\n {\n data: {\n id: string;\n label: string;\n namespace: Namespace;\n generateDerivationPath: (index: string) => string;\n }[];\n }\n>;\ntype DetailsProperty = Property<\n 'details',\n {\n mobileWallet?: boolean;\n showOnMobile?: boolean;\n isContractWallet?: boolean;\n }\n>;\ntype SignersProperty = Property<\n 'signers',\n {\n getSigners: () => Promise<SignerFactory>;\n }\n>;\n\nexport type ProviderMetadata = {\n name: string;\n icon: string;\n extensions: Partial<Record<Browsers, string>>;\n properties?: Array<\n | NamespacesProperty\n | DerivationPathProperty\n | DetailsProperty\n | SignersProperty\n >;\n};\n\nexport interface ProviderConfig {\n metadata: ProviderMetadata;\n}\n\nexport type ProviderInfo = ProviderConfig;\n\ninterface ProviderData {\n installed: boolean;\n}\n\ninterface ProviderItem {\n config: ProviderConfig;\n data: ProviderData;\n error: unknown;\n}\n\ntype ProviderState = {\n events: ConsumableEvents;\n list: Record<string, ProviderItem>;\n};\ninterface ProviderActions {\n addProvider: (id: string, config: ProviderConfig) => void;\n removeProvider: (id: string) => void;\n updateStatus: <K extends keyof ProviderData>(\n id: string,\n key: K,\n value: ProviderData[K]\n ) => void;\n\n _produceEventsWhenUpdatingStatus: <K extends keyof ProviderData>(\n provider: ProviderItem,\n id: string,\n key: K,\n value: ProviderData[K]\n ) => void;\n}\n\ninterface ProviderSelectors {\n /**\n * Provider has a limited state to itself, to be compatible with legacy, we try to produce same object as legacy\n * which includes namespace state as well.\n */\n guessNamespacesState: (id: string) => InternalProviderState;\n}\n\nexport type ProviderStore = ProviderState & ProviderActions & ProviderSelectors;\ntype ProvidersStateCreator = StateCreator<State, [], [], ProviderStore>;\n\nconst providersStore: ProvidersStateCreator = (set, get) => ({\n events: new ConsumableEvents(),\n\n list: {},\n addProvider: (id, config) => {\n const item = {\n data: {\n installed: false,\n },\n error: '',\n config,\n };\n\n set(\n produce((state: State) => {\n state.providers.list[id] = item;\n })\n );\n },\n removeProvider: (id) => {\n set(\n produce((state: State) => {\n delete state.providers.list[id];\n })\n );\n },\n updateStatus: (id, key, value) => {\n const provider = get().providers.list[id];\n if (!provider) {\n throw new Error(`No namespace namespace with '${id}' found.`);\n }\n\n get().providers._produceEventsWhenUpdatingStatus(provider, id, key, value);\n\n set(\n produce((state: State) => {\n state.providers.list[id].data[key] = value;\n })\n );\n },\n guessNamespacesState: (providerId: string): InternalProviderState => {\n return guessProviderStateSelector(get(), providerId);\n },\n\n _produceEventsWhenUpdatingStatus: (_provider, id, key, _value) => {\n if (key === 'installed') {\n const event: ProviderDetectedEvent = {\n type: 'provider_detected',\n provider: id,\n };\n\n get().providers.events.push(event);\n }\n },\n});\n\nexport { providersStore };\n", "import type { Actions, Context, Operators } from '../hub/namespaces/types.js';\nimport type { AnyFunction, FunctionWithContext } from '../types/actions.js';\n\nexport interface ActionByBuilder<T, Context> {\n actionName: keyof T;\n and: Operators<T>;\n or: Operators<T>;\n after: Operators<T>;\n before: Operators<T>;\n action: FunctionWithContext<T[keyof T], Context>;\n}\n\n/*\n * TODO:\n * Currently, to use this builder you will write something like this:\n * new ActionBuilder<EvmActions, 'disconnect'>('disconnect').after(....)\n *\n * I couldn't figure it out to be able typescript infer the constructor value as key of actions.\n * Ideal usage:\n * new ActionBuilder<EvmActions>('disconnect').after(....)\n *\n */\nexport class ActionBuilder<T extends Actions<T>, K extends keyof T> {\n readonly name: K;\n #and: Operators<T> = new Map();\n #or: Operators<T> = new Map();\n #after: Operators<T> = new Map();\n #before: Operators<T> = new Map();\n #action: FunctionWithContext<T[keyof T], Context<T>> | undefined;\n\n constructor(name: K) {\n this.name = name;\n }\n\n public and(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#and.has(this.name)) {\n this.#and.set(this.name, []);\n }\n this.#and.get(this.name)?.push(action);\n return this;\n }\n\n public or(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#or.has(this.name)) {\n this.#or.set(this.name, []);\n }\n this.#or.get(this.name)?.push(action);\n return this;\n }\n\n public before(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#before.has(this.name)) {\n this.#before.set(this.name, []);\n }\n this.#before.get(this.name)?.push(action);\n return this;\n }\n\n public after(action: FunctionWithContext<AnyFunction, Context<T>>) {\n if (!this.#after.has(this.name)) {\n this.#after.set(this.name, []);\n }\n this.#after.get(this.name)?.push(action);\n return this;\n }\n\n public action(action: FunctionWithContext<T[keyof T], Context<T>>) {\n this.#action = action;\n return this;\n }\n\n public build(): ActionByBuilder<T, Context<T>> {\n if (!this.#action) {\n throw new Error('Your action builder should includes an action.');\n }\n\n return {\n actionName: this.name,\n action: this.#action,\n before: this.#before,\n after: this.#after,\n and: this.#and,\n or: this.#or,\n };\n }\n}\n", "/*\n * It is not a good idea to re-export all of CAIP because if they have a breaking change, we will break as well.\n * It would be better to create an abstraction over them and export our own interface to ensure it is under our control.\n */\nexport * as CAIP from 'caip';\n\nexport { generateStoreId } from '../hub/helpers.js';\nexport * from './versions.js';\n", "import { AccountId } from 'caip';\n\nexport function isValidCaipAddress(address: string): boolean {\n try {\n AccountId.parse(address);\n return true;\n } catch {\n return false;\n }\n}\n", "import type {\n Accounts,\n AccountsWithActiveChain,\n} from './../../types/accounts.js';\nimport type { Context } from '../../hub/namespaces/mod.js';\n\nimport { isValidCaipAddress } from './helpers.js';\n\nexport function connectAndUpdateStateForSingleNetwork(\n context: Context,\n accounts: Accounts\n) {\n if (!accounts.every(isValidCaipAddress)) {\n throw new Error(\n `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts}`\n );\n }\n\n const [, setState] = context.state();\n setState('accounts', accounts);\n setState('connected', true);\n return accounts;\n}\n\nexport function connectAndUpdateStateForMultiNetworks(\n context: Context,\n accounts: AccountsWithActiveChain\n) {\n if (!accounts.accounts.every(isValidCaipAddress)) {\n throw new Error(\n `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts.accounts}`\n );\n }\n\n const [, setState] = context.state();\n setState('accounts', accounts.accounts);\n setState('network', accounts.network);\n setState('connected', true);\n return accounts;\n}\n\nexport const recommended = [];\n", "import type { Context } from '../../hub/namespaces/mod.js';\n\nexport function intoConnecting(context: Context) {\n const [, setState] = context.state();\n setState('connecting', true);\n}\n\n// Please consider if you are going to add something here, make sure it works on all namespaces.\nexport const recommended = [['connect', intoConnecting] as const];\n", "import { recommended as commonRecommended } from '../common/before.js';\n\nexport const recommended = [...commonRecommended];\n", "import type { TronActions } from './types.js';\n\nimport { ActionBuilder } from '../../mod.js';\nimport { intoConnectionFinished } from '../common/after.js';\nimport { connectAndUpdateStateForSingleNetwork } from '../common/and.js';\nimport { intoConnecting } from '../common/before.js';\n\nexport const connect = () =>\n new ActionBuilder<TronActions, 'connect'>('connect')\n .and(connectAndUpdateStateForSingleNetwork)\n .before(intoConnecting)\n .after(intoConnectionFinished);\n\nexport const canEagerConnect = () =>\n new ActionBuilder<TronActions, 'canEagerConnect'>('canEagerConnect');\n\nexport const getAllowance = () =>\n new ActionBuilder<TronActions, 'getAllowance'>('getAllowance');\n\nexport const buildApproveTransaction = () =>\n new ActionBuilder<TronActions, 'buildApproveTransaction'>(\n 'buildApproveTransaction'\n );\n\nexport const getTransactionInfo = () =>\n new ActionBuilder<TronActions, 'getTransactionInfo'>('getTransactionInfo');\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["actions_exports", "__export", "buildApproveTransaction", "getAllowance", "getTransactionInfo", "recommended", "disconnect", "context", "setState", "__name", "recommended", "CAIP_NAMESPACE", "CAIP_TRON_CHAIN_ID", "APPROVE_FUNCTION_SELECTOR", "utils_exports", "__export", "buildApprovePayload", "formatAccountsToCAIP", "getTronWeb", "hexAddressToTronBase58", "isTronNamespace", "getNamespaceFromCaip2ChainId", "AccountId", "isTronNamespace", "caip2ChainId", "getNamespaceFromCaip2ChainId", "CAIP_NAMESPACE", "__name", "buildApprovePayload", "transaction", "feeLimit", "call", "APPROVE_FUNCTION_SELECTOR", "getTronWeb", "instance", "tronInstance", "TRON_HEX_ADDRESS_PREFIX", "hexAddressToTronBase58", "tronWeb", "address", "tronHex", "formatAccountsToCAIP", "accounts", "account", "AccountId", "CAIP_TRON_CHAIN_ID", "recommended", "getAllowance", "instance", "_context", "params", "tronWeb", "getTronWeb", "owner", "hexAddressToTronBase58", "token", "spender", "result", "constant_result", "__name", "buildApproveTransaction", "feeLimit", "transaction", "APPROVE_FUNCTION_SELECTOR", "buildApprovePayload", "getTransactionInfo", "txID", "after_exports", "__export", "recommended", "intoConnectionFinished", "context", "setState", "__name", "recommended", "recommended", "and_exports", "__export", "recommended", "createZustandStore", "produce", "produce", "ActionBuilder", "__name", "#and", "#or", "#after", "#before", "#action", "name", "action", "CAIP", "AccountId", "isValidCaipAddress", "address", "AccountId", "__name", "connectAndUpdateStateForSingleNetwork", "context", "accounts", "isValidCaipAddress", "setState", "__name", "intoConnecting", "context", "setState", "__name", "recommended", "recommended", "connectAndUpdateStateForSingleNetwork", "before_exports", "__export", "recommended", "recommended", "builders_exports", "__export", "buildApproveTransaction", "canEagerConnect", "connect", "getAllowance", "getTransactionInfo", "connect", "__name", "ActionBuilder", "connectAndUpdateStateForSingleNetwork", "intoConnecting", "intoConnectionFinished", "canEagerConnect", "getAllowance", "buildApproveTransaction", "getTransactionInfo"]
|
|
7
7
|
}
|
|
@@ -3,6 +3,153 @@ import type { AutoImplementedActionsByRecommended, CommonActions } from '../comm
|
|
|
3
3
|
export interface TronActions extends AutoImplementedActionsByRecommended, CommonActions {
|
|
4
4
|
connect: () => Promise<Accounts>;
|
|
5
5
|
canEagerConnect: () => Promise<boolean>;
|
|
6
|
+
/** Reads the current TRC-20 allowance, returned as a decimal string. */
|
|
7
|
+
getAllowance: (params: TronAllowanceParams) => Promise<string>;
|
|
8
|
+
/** Builds (via the node) a ready-to-sign TRC-20 `approve` transaction. */
|
|
9
|
+
buildApproveTransaction: (params: TronApproveParams) => Promise<TronBuiltTransaction>;
|
|
10
|
+
/** Reads a transaction's on-chain info (fields are empty while unconfirmed). */
|
|
11
|
+
getTransactionInfo: (txID: string) => Promise<TronTransactionInfo>;
|
|
12
|
+
}
|
|
13
|
+
/** Addresses are provided in 0x-hex form and converted to Tron form internally. */
|
|
14
|
+
export type TronAllowanceParams = {
|
|
15
|
+
token: string;
|
|
16
|
+
owner: string;
|
|
17
|
+
spender: string;
|
|
18
|
+
};
|
|
19
|
+
export type TronApproveParams = {
|
|
20
|
+
token: string;
|
|
21
|
+
owner: string;
|
|
22
|
+
spender: string;
|
|
23
|
+
/** Amount to approve, as an integer string in the token's smallest unit. */
|
|
24
|
+
amount: string;
|
|
25
|
+
/** Fee limit in SUN; defaults to DEFAULT_APPROVE_FEE_LIMIT when omitted. */
|
|
26
|
+
feeLimit?: number;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The focused TronWeb surface the repo calls — both these namespace actions and
|
|
30
|
+
* the Tron signer, which is handed this same injected instance. `tronweb` is not
|
|
31
|
+
* a repo dependency (wallets use the wallet-injected instance), so we type only
|
|
32
|
+
* the methods we use rather than pulling the package's declarations.
|
|
33
|
+
*
|
|
34
|
+
* @see https://tronweb.network/docu/docs/intro TronWeb API reference — used
|
|
35
|
+
* here: `transactionBuilder.triggerConstantContract` / `triggerSmartContract`,
|
|
36
|
+
* `trx.getUnconfirmedTransactionInfo` / `sign` / `signMessageV2` /
|
|
37
|
+
* `sendRawTransaction`, and `address.fromHex`.
|
|
38
|
+
*/
|
|
39
|
+
export interface TronWebApi {
|
|
40
|
+
defaultAddress: {
|
|
41
|
+
base58: string;
|
|
42
|
+
};
|
|
43
|
+
transactionBuilder: {
|
|
44
|
+
triggerConstantContract: (contractAddress: string, functionSelector: string, options: TriggerOptions, parameters: TriggerParameter[], issuerAddress: string) => Promise<TriggerConstantContractResult>;
|
|
45
|
+
triggerSmartContract: (contractAddress: string, functionSelector: string, options: TriggerOptions, parameters: TriggerParameter[], issuerAddress: string) => Promise<TriggerSmartContractResult>;
|
|
46
|
+
};
|
|
47
|
+
trx: {
|
|
48
|
+
/**
|
|
49
|
+
* Full-node lookup that returns the info as soon as the tx is in a block
|
|
50
|
+
* (~3s). `getTransactionInfo` queries the solidity node instead and returns
|
|
51
|
+
* an empty object until the tx solidifies (~60s), so it is unsuitable for
|
|
52
|
+
* promptly resolving approve-transaction status.
|
|
53
|
+
*/
|
|
54
|
+
getUnconfirmedTransactionInfo: (txID: string) => Promise<TronTransactionInfo>;
|
|
55
|
+
signMessageV2: (message: string) => Promise<string>;
|
|
56
|
+
sign: (transaction: object) => Promise<TronSignedTransaction>;
|
|
57
|
+
sendRawTransaction: (signedTransaction: TronSignedTransaction) => Promise<TronBroadcastReceipt>;
|
|
58
|
+
};
|
|
59
|
+
address: {
|
|
60
|
+
fromHex: (hexAddress: string) => string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** A contract-call parameter, e.g. `{ type: 'address', value: 'T...' }`. */
|
|
64
|
+
export type TriggerParameter = {
|
|
65
|
+
type: string;
|
|
66
|
+
value: string;
|
|
67
|
+
};
|
|
68
|
+
export type TriggerOptions = {
|
|
69
|
+
feeLimit?: number;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Describes the contract call that produced a transaction.
|
|
73
|
+
*
|
|
74
|
+
* Wallets that let the user edit an approve amount rebuild the transaction from
|
|
75
|
+
* this rather than decoding `raw_data`, so it has to carry everything needed to
|
|
76
|
+
* re-issue the call. Server-built transactions include it; TronWeb's
|
|
77
|
+
* `transactionBuilder` does not, so the Tron namespace adds it.
|
|
78
|
+
*/
|
|
79
|
+
export interface TronTransactionPayload {
|
|
80
|
+
/** The kind of client the call came from; server-built transactions use 'WEB'. */
|
|
81
|
+
type: string;
|
|
82
|
+
owner_address: string;
|
|
83
|
+
call_value: number;
|
|
84
|
+
contract_address: string;
|
|
85
|
+
fee_limit: number;
|
|
86
|
+
function_selector: string;
|
|
87
|
+
/** The ABI-encoded arguments, i.e. the call data without its selector. */
|
|
88
|
+
parameter: string;
|
|
89
|
+
chainType: string | null;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A transaction as returned by TronWeb's `transactionBuilder` — the subset of
|
|
93
|
+
* fields the Tron signer consumes to sign and broadcast.
|
|
94
|
+
*/
|
|
95
|
+
export interface TronBuiltTransaction {
|
|
96
|
+
txID: string;
|
|
97
|
+
raw_data: unknown;
|
|
98
|
+
raw_data_hex: string;
|
|
99
|
+
visible?: boolean;
|
|
100
|
+
__payload__?: TronTransactionPayload;
|
|
101
|
+
}
|
|
102
|
+
/** The contract call inside a built transaction's `raw_data`. */
|
|
103
|
+
export interface TronRawDataContract {
|
|
104
|
+
parameter?: {
|
|
105
|
+
value?: {
|
|
106
|
+
data?: string;
|
|
107
|
+
owner_address?: string;
|
|
108
|
+
contract_address?: string;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** A transaction after signing, carrying the id it was signed under. */
|
|
113
|
+
export interface TronSignedTransaction {
|
|
114
|
+
txID?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The response to a broadcast. Wallet-injected TronWeb instances disagree on
|
|
118
|
+
* where the transaction id lives, so both known shapes are optional here.
|
|
119
|
+
*/
|
|
120
|
+
export interface TronBroadcastReceipt {
|
|
121
|
+
txid?: string;
|
|
122
|
+
transaction?: {
|
|
123
|
+
txID?: string;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export interface TriggerConstantContractResult {
|
|
127
|
+
result: {
|
|
128
|
+
result: boolean;
|
|
129
|
+
};
|
|
130
|
+
/** ABI-encoded return words; `constant_result[0]` holds the allowance. */
|
|
131
|
+
constant_result: string[];
|
|
132
|
+
transaction: TronBuiltTransaction;
|
|
133
|
+
}
|
|
134
|
+
export interface TriggerSmartContractResult {
|
|
135
|
+
result: {
|
|
136
|
+
result: boolean;
|
|
137
|
+
};
|
|
138
|
+
transaction: TronBuiltTransaction;
|
|
139
|
+
}
|
|
140
|
+
/** The receipt embedded in a Tron transaction's on-chain info. */
|
|
141
|
+
export interface TronTransactionReceipt {
|
|
142
|
+
/** e.g. 'SUCCESS' | 'REVERT' | 'OUT_OF_ENERGY'; absent while unconfirmed. */
|
|
143
|
+
result?: string;
|
|
144
|
+
}
|
|
145
|
+
export interface TronTransactionInfo {
|
|
146
|
+
id?: string;
|
|
147
|
+
blockNumber?: number;
|
|
148
|
+
receipt?: TronTransactionReceipt;
|
|
149
|
+
}
|
|
150
|
+
/** The injected Tron provider instance, which exposes a TronWeb instance. */
|
|
151
|
+
export interface ProviderAPI {
|
|
152
|
+
[key: string]: any;
|
|
153
|
+
tronWeb: TronWebApi;
|
|
6
154
|
}
|
|
7
|
-
export type ProviderAPI = Record<string, any>;
|
|
8
155
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EACV,mCAAmC,EACnC,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,WACf,SAAQ,mCAAmC,EACzC,aAAa;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
import type { ProviderAPI, TronBuiltTransaction, TronTransactionPayload, TronWebApi } from './types.js';
|
|
1
2
|
export declare function isTronNamespace(caip2ChainId: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Describes a built approve call the way a server-built transaction does.
|
|
5
|
+
*
|
|
6
|
+
* Wallets that let the user choose the allowance rebuild the transaction from
|
|
7
|
+
* `__payload__` instead of decoding `raw_data`. TronWeb's `transactionBuilder`
|
|
8
|
+
* leaves it out, and given an empty one TronLink cannot re-issue the call and
|
|
9
|
+
* reports "Modification failed", so the approve can never be signed there.
|
|
10
|
+
*
|
|
11
|
+
* The values are read back out of the built transaction rather than recomputed,
|
|
12
|
+
* so they cannot drift from what was actually built and signed.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildApprovePayload(transaction: TronBuiltTransaction, feeLimit: number): TronTransactionPayload | undefined;
|
|
15
|
+
/** The wallet-injected TronWeb instance, or a readable error when absent. */
|
|
16
|
+
export declare function getTronWeb(instance: () => ProviderAPI | undefined): TronWebApi;
|
|
17
|
+
/**
|
|
18
|
+
* Prerequisite addresses arrive in 0x-hex (EVM-style) form; TronWeb expects a
|
|
19
|
+
* Tron address. Convert `0x<20-bytes>` → `41<20-bytes>` → Base58.
|
|
20
|
+
*/
|
|
21
|
+
export declare function hexAddressToTronBase58(tronWeb: TronWebApi, address: string): string;
|
|
2
22
|
export declare function formatAccountsToCAIP(accounts: string[]): `${string}:${string}:${string}`[];
|
|
3
23
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/namespaces/tron/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,oBAAoB,EAEpB,sBAAsB,EACtB,UAAU,EACX,MAAM,YAAY,CAAC;AAapB,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,oBAAoB,EACjC,QAAQ,EAAE,MAAM,GACf,sBAAsB,GAAG,SAAS,CAoBpC;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,WAAW,GAAG,SAAS,GACtC,UAAU,CAMZ;AAKD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAGR;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,qCAWtD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rango-dev/wallets-core",
|
|
3
|
-
"version": "0.62.1",
|
|
3
|
+
"version": "0.62.2-next.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "./src/mod.ts",
|
|
@@ -82,11 +82,11 @@
|
|
|
82
82
|
"xrpl": "^4.2.0"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"@hub3js/std": "^0.
|
|
85
|
+
"@hub3js/std": "^0.5.0",
|
|
86
86
|
"@stellar/stellar-sdk": "^15.0.1",
|
|
87
87
|
"caip": "^1.1.1",
|
|
88
88
|
"immer": "^10.0.4",
|
|
89
|
-
"rango-types": "^0.
|
|
89
|
+
"rango-types": "^0.6.0",
|
|
90
90
|
"zustand": "^4.5.2"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
@@ -1,3 +1,106 @@
|
|
|
1
|
+
import type { ProviderAPI, TronActions } from './types.js';
|
|
2
|
+
import type { Context } from '../../hub/namespaces/mod.js';
|
|
3
|
+
import type { FunctionWithContext } from '../../types/actions.js';
|
|
4
|
+
|
|
1
5
|
import { recommended as commonRecommended } from '../common/actions.js';
|
|
2
6
|
|
|
7
|
+
import {
|
|
8
|
+
APPROVE_FUNCTION_SELECTOR,
|
|
9
|
+
DEFAULT_APPROVE_FEE_LIMIT,
|
|
10
|
+
} from './constants.js';
|
|
11
|
+
import {
|
|
12
|
+
buildApprovePayload,
|
|
13
|
+
getTronWeb,
|
|
14
|
+
hexAddressToTronBase58,
|
|
15
|
+
} from './utils.js';
|
|
16
|
+
|
|
3
17
|
export const recommended = [...commonRecommended];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Reads a TRC-20 `allowance(owner, spender)` via a constant contract call and
|
|
21
|
+
* returns it as a decimal string.
|
|
22
|
+
*/
|
|
23
|
+
export function getAllowance(
|
|
24
|
+
instance: () => ProviderAPI | undefined
|
|
25
|
+
): FunctionWithContext<TronActions['getAllowance'], Context> {
|
|
26
|
+
return async (_context, params) => {
|
|
27
|
+
const tronWeb = getTronWeb(instance);
|
|
28
|
+
const owner = hexAddressToTronBase58(tronWeb, params.owner);
|
|
29
|
+
const token = hexAddressToTronBase58(tronWeb, params.token);
|
|
30
|
+
const spender = hexAddressToTronBase58(tronWeb, params.spender);
|
|
31
|
+
|
|
32
|
+
const { result, constant_result } =
|
|
33
|
+
await tronWeb.transactionBuilder.triggerConstantContract(
|
|
34
|
+
token,
|
|
35
|
+
'allowance(address,address)',
|
|
36
|
+
{},
|
|
37
|
+
[
|
|
38
|
+
{ type: 'address', value: owner },
|
|
39
|
+
{ type: 'address', value: spender },
|
|
40
|
+
],
|
|
41
|
+
owner
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
if (!result?.result || !constant_result?.length) {
|
|
45
|
+
throw new Error('Failed to read the TRC-20 allowance.');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return BigInt(`0x${constant_result[0]}`).toString();
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Builds (via the node) a ready-to-sign `approve(spender, amount)` transaction
|
|
54
|
+
* on the TRC-20 token contract.
|
|
55
|
+
*
|
|
56
|
+
* The transaction carries TronWeb's default 60s expiration, which is the same
|
|
57
|
+
* window server-built approvals use.
|
|
58
|
+
*/
|
|
59
|
+
export function buildApproveTransaction(
|
|
60
|
+
instance: () => ProviderAPI | undefined
|
|
61
|
+
): FunctionWithContext<TronActions['buildApproveTransaction'], Context> {
|
|
62
|
+
return async (_context, params) => {
|
|
63
|
+
const tronWeb = getTronWeb(instance);
|
|
64
|
+
const owner = hexAddressToTronBase58(tronWeb, params.owner);
|
|
65
|
+
const token = hexAddressToTronBase58(tronWeb, params.token);
|
|
66
|
+
const spender = hexAddressToTronBase58(tronWeb, params.spender);
|
|
67
|
+
|
|
68
|
+
const feeLimit = params.feeLimit ?? DEFAULT_APPROVE_FEE_LIMIT;
|
|
69
|
+
const { result, transaction } =
|
|
70
|
+
await tronWeb.transactionBuilder.triggerSmartContract(
|
|
71
|
+
token,
|
|
72
|
+
APPROVE_FUNCTION_SELECTOR,
|
|
73
|
+
{ feeLimit },
|
|
74
|
+
[
|
|
75
|
+
{ type: 'address', value: spender },
|
|
76
|
+
{ type: 'uint256', value: params.amount },
|
|
77
|
+
],
|
|
78
|
+
owner
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
if (!result?.result) {
|
|
82
|
+
throw new Error('Failed to build the TRC-20 approve transaction.');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* `transactionBuilder` returns only the consensus fields. A server-built
|
|
87
|
+
* transaction also carries `__payload__`, which wallets use to re-issue the
|
|
88
|
+
* call when the user edits the allowance, so add it here too.
|
|
89
|
+
*/
|
|
90
|
+
return {
|
|
91
|
+
...transaction,
|
|
92
|
+
__payload__: buildApprovePayload(transaction, feeLimit),
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Reads a transaction's on-chain info (empty while the tx is unconfirmed). */
|
|
98
|
+
export function getTransactionInfo(
|
|
99
|
+
instance: () => ProviderAPI | undefined
|
|
100
|
+
): FunctionWithContext<TronActions['getTransactionInfo'], Context> {
|
|
101
|
+
return async (_context, txID) => {
|
|
102
|
+
const tronWeb = getTronWeb(instance);
|
|
103
|
+
// Full node (not solidity), so the info is available right after inclusion.
|
|
104
|
+
return tronWeb.trx.getUnconfirmedTransactionInfo(txID);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -13,3 +13,14 @@ export const connect = () =>
|
|
|
13
13
|
|
|
14
14
|
export const canEagerConnect = () =>
|
|
15
15
|
new ActionBuilder<TronActions, 'canEagerConnect'>('canEagerConnect');
|
|
16
|
+
|
|
17
|
+
export const getAllowance = () =>
|
|
18
|
+
new ActionBuilder<TronActions, 'getAllowance'>('getAllowance');
|
|
19
|
+
|
|
20
|
+
export const buildApproveTransaction = () =>
|
|
21
|
+
new ActionBuilder<TronActions, 'buildApproveTransaction'>(
|
|
22
|
+
'buildApproveTransaction'
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const getTransactionInfo = () =>
|
|
26
|
+
new ActionBuilder<TronActions, 'getTransactionInfo'>('getTransactionInfo');
|
|
@@ -6,3 +6,18 @@
|
|
|
6
6
|
// if the value needs to be change make sure you will update mapCaipNamespaceToLegacyNetworkName as well
|
|
7
7
|
export const CAIP_NAMESPACE = 'tron';
|
|
8
8
|
export const CAIP_TRON_CHAIN_ID = 'tron';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Default fee limit (in SUN) for a client-built TRC-20 approve transaction.
|
|
12
|
+
* 250 TRX — matches the value the backend used for server-built approvals.
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_APPROVE_FEE_LIMIT = 250_000_000;
|
|
15
|
+
|
|
16
|
+
/** The TRC-20 call the approve prerequisite issues. */
|
|
17
|
+
export const APPROVE_FUNCTION_SELECTOR = 'approve(address,uint256)';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Length in hex characters of the function selector that prefixes a call's
|
|
21
|
+
* data: 4 bytes, two characters each.
|
|
22
|
+
*/
|
|
23
|
+
export const FUNCTION_SELECTOR_HEX_LENGTH = 8;
|
|
@@ -9,7 +9,173 @@ export interface TronActions
|
|
|
9
9
|
CommonActions {
|
|
10
10
|
connect: () => Promise<Accounts>;
|
|
11
11
|
canEagerConnect: () => Promise<boolean>;
|
|
12
|
+
/** Reads the current TRC-20 allowance, returned as a decimal string. */
|
|
13
|
+
getAllowance: (params: TronAllowanceParams) => Promise<string>;
|
|
14
|
+
/** Builds (via the node) a ready-to-sign TRC-20 `approve` transaction. */
|
|
15
|
+
buildApproveTransaction: (
|
|
16
|
+
params: TronApproveParams
|
|
17
|
+
) => Promise<TronBuiltTransaction>;
|
|
18
|
+
/** Reads a transaction's on-chain info (fields are empty while unconfirmed). */
|
|
19
|
+
getTransactionInfo: (txID: string) => Promise<TronTransactionInfo>;
|
|
12
20
|
}
|
|
13
21
|
|
|
14
|
-
|
|
15
|
-
export type
|
|
22
|
+
/** Addresses are provided in 0x-hex form and converted to Tron form internally. */
|
|
23
|
+
export type TronAllowanceParams = {
|
|
24
|
+
token: string;
|
|
25
|
+
owner: string;
|
|
26
|
+
spender: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type TronApproveParams = {
|
|
30
|
+
token: string;
|
|
31
|
+
owner: string;
|
|
32
|
+
spender: string;
|
|
33
|
+
/** Amount to approve, as an integer string in the token's smallest unit. */
|
|
34
|
+
amount: string;
|
|
35
|
+
/** Fee limit in SUN; defaults to DEFAULT_APPROVE_FEE_LIMIT when omitted. */
|
|
36
|
+
feeLimit?: number;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The focused TronWeb surface the repo calls — both these namespace actions and
|
|
41
|
+
* the Tron signer, which is handed this same injected instance. `tronweb` is not
|
|
42
|
+
* a repo dependency (wallets use the wallet-injected instance), so we type only
|
|
43
|
+
* the methods we use rather than pulling the package's declarations.
|
|
44
|
+
*
|
|
45
|
+
* @see https://tronweb.network/docu/docs/intro TronWeb API reference — used
|
|
46
|
+
* here: `transactionBuilder.triggerConstantContract` / `triggerSmartContract`,
|
|
47
|
+
* `trx.getUnconfirmedTransactionInfo` / `sign` / `signMessageV2` /
|
|
48
|
+
* `sendRawTransaction`, and `address.fromHex`.
|
|
49
|
+
*/
|
|
50
|
+
export interface TronWebApi {
|
|
51
|
+
defaultAddress: { base58: string };
|
|
52
|
+
transactionBuilder: {
|
|
53
|
+
triggerConstantContract: (
|
|
54
|
+
contractAddress: string,
|
|
55
|
+
functionSelector: string,
|
|
56
|
+
options: TriggerOptions,
|
|
57
|
+
parameters: TriggerParameter[],
|
|
58
|
+
issuerAddress: string
|
|
59
|
+
) => Promise<TriggerConstantContractResult>;
|
|
60
|
+
triggerSmartContract: (
|
|
61
|
+
contractAddress: string,
|
|
62
|
+
functionSelector: string,
|
|
63
|
+
options: TriggerOptions,
|
|
64
|
+
parameters: TriggerParameter[],
|
|
65
|
+
issuerAddress: string
|
|
66
|
+
) => Promise<TriggerSmartContractResult>;
|
|
67
|
+
};
|
|
68
|
+
trx: {
|
|
69
|
+
/**
|
|
70
|
+
* Full-node lookup that returns the info as soon as the tx is in a block
|
|
71
|
+
* (~3s). `getTransactionInfo` queries the solidity node instead and returns
|
|
72
|
+
* an empty object until the tx solidifies (~60s), so it is unsuitable for
|
|
73
|
+
* promptly resolving approve-transaction status.
|
|
74
|
+
*/
|
|
75
|
+
getUnconfirmedTransactionInfo: (
|
|
76
|
+
txID: string
|
|
77
|
+
) => Promise<TronTransactionInfo>;
|
|
78
|
+
signMessageV2: (message: string) => Promise<string>;
|
|
79
|
+
sign: (transaction: object) => Promise<TronSignedTransaction>;
|
|
80
|
+
sendRawTransaction: (
|
|
81
|
+
signedTransaction: TronSignedTransaction
|
|
82
|
+
) => Promise<TronBroadcastReceipt>;
|
|
83
|
+
};
|
|
84
|
+
address: {
|
|
85
|
+
fromHex: (hexAddress: string) => string;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** A contract-call parameter, e.g. `{ type: 'address', value: 'T...' }`. */
|
|
90
|
+
export type TriggerParameter = { type: string; value: string };
|
|
91
|
+
export type TriggerOptions = { feeLimit?: number };
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Describes the contract call that produced a transaction.
|
|
95
|
+
*
|
|
96
|
+
* Wallets that let the user edit an approve amount rebuild the transaction from
|
|
97
|
+
* this rather than decoding `raw_data`, so it has to carry everything needed to
|
|
98
|
+
* re-issue the call. Server-built transactions include it; TronWeb's
|
|
99
|
+
* `transactionBuilder` does not, so the Tron namespace adds it.
|
|
100
|
+
*/
|
|
101
|
+
export interface TronTransactionPayload {
|
|
102
|
+
/** The kind of client the call came from; server-built transactions use 'WEB'. */
|
|
103
|
+
type: string;
|
|
104
|
+
owner_address: string;
|
|
105
|
+
call_value: number;
|
|
106
|
+
contract_address: string;
|
|
107
|
+
fee_limit: number;
|
|
108
|
+
function_selector: string;
|
|
109
|
+
/** The ABI-encoded arguments, i.e. the call data without its selector. */
|
|
110
|
+
parameter: string;
|
|
111
|
+
chainType: string | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* A transaction as returned by TronWeb's `transactionBuilder` — the subset of
|
|
116
|
+
* fields the Tron signer consumes to sign and broadcast.
|
|
117
|
+
*/
|
|
118
|
+
export interface TronBuiltTransaction {
|
|
119
|
+
txID: string;
|
|
120
|
+
raw_data: unknown;
|
|
121
|
+
raw_data_hex: string;
|
|
122
|
+
visible?: boolean;
|
|
123
|
+
__payload__?: TronTransactionPayload;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** The contract call inside a built transaction's `raw_data`. */
|
|
127
|
+
export interface TronRawDataContract {
|
|
128
|
+
parameter?: {
|
|
129
|
+
value?: {
|
|
130
|
+
data?: string;
|
|
131
|
+
owner_address?: string;
|
|
132
|
+
contract_address?: string;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** A transaction after signing, carrying the id it was signed under. */
|
|
138
|
+
export interface TronSignedTransaction {
|
|
139
|
+
txID?: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The response to a broadcast. Wallet-injected TronWeb instances disagree on
|
|
144
|
+
* where the transaction id lives, so both known shapes are optional here.
|
|
145
|
+
*/
|
|
146
|
+
export interface TronBroadcastReceipt {
|
|
147
|
+
txid?: string;
|
|
148
|
+
transaction?: { txID?: string };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface TriggerConstantContractResult {
|
|
152
|
+
result: { result: boolean };
|
|
153
|
+
/** ABI-encoded return words; `constant_result[0]` holds the allowance. */
|
|
154
|
+
constant_result: string[];
|
|
155
|
+
transaction: TronBuiltTransaction;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface TriggerSmartContractResult {
|
|
159
|
+
result: { result: boolean };
|
|
160
|
+
transaction: TronBuiltTransaction;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** The receipt embedded in a Tron transaction's on-chain info. */
|
|
164
|
+
export interface TronTransactionReceipt {
|
|
165
|
+
/** e.g. 'SUCCESS' | 'REVERT' | 'OUT_OF_ENERGY'; absent while unconfirmed. */
|
|
166
|
+
result?: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface TronTransactionInfo {
|
|
170
|
+
id?: string;
|
|
171
|
+
blockNumber?: number;
|
|
172
|
+
receipt?: TronTransactionReceipt;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** The injected Tron provider instance, which exposes a TronWeb instance. */
|
|
176
|
+
export interface ProviderAPI {
|
|
177
|
+
// Providers attach extra members (request, ready, …) we don't type here.
|
|
178
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
179
|
+
[key: string]: any;
|
|
180
|
+
tronWeb: TronWebApi;
|
|
181
|
+
}
|
|
@@ -1,14 +1,88 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ProviderAPI,
|
|
3
|
+
TronBuiltTransaction,
|
|
4
|
+
TronRawDataContract,
|
|
5
|
+
TronTransactionPayload,
|
|
6
|
+
TronWebApi,
|
|
7
|
+
} from './types.js';
|
|
1
8
|
import type { CaipAccount } from '../common/mod.js';
|
|
2
9
|
|
|
3
10
|
import { getNamespaceFromCaip2ChainId } from '@hub3js/std/utils';
|
|
4
11
|
import { AccountId } from 'caip';
|
|
5
12
|
|
|
6
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
APPROVE_FUNCTION_SELECTOR,
|
|
15
|
+
CAIP_NAMESPACE,
|
|
16
|
+
CAIP_TRON_CHAIN_ID,
|
|
17
|
+
FUNCTION_SELECTOR_HEX_LENGTH,
|
|
18
|
+
} from './constants.js';
|
|
7
19
|
|
|
8
20
|
export function isTronNamespace(caip2ChainId: string): boolean {
|
|
9
21
|
return getNamespaceFromCaip2ChainId(caip2ChainId) === CAIP_NAMESPACE;
|
|
10
22
|
}
|
|
11
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Describes a built approve call the way a server-built transaction does.
|
|
26
|
+
*
|
|
27
|
+
* Wallets that let the user choose the allowance rebuild the transaction from
|
|
28
|
+
* `__payload__` instead of decoding `raw_data`. TronWeb's `transactionBuilder`
|
|
29
|
+
* leaves it out, and given an empty one TronLink cannot re-issue the call and
|
|
30
|
+
* reports "Modification failed", so the approve can never be signed there.
|
|
31
|
+
*
|
|
32
|
+
* The values are read back out of the built transaction rather than recomputed,
|
|
33
|
+
* so they cannot drift from what was actually built and signed.
|
|
34
|
+
*/
|
|
35
|
+
export function buildApprovePayload(
|
|
36
|
+
transaction: TronBuiltTransaction,
|
|
37
|
+
feeLimit: number
|
|
38
|
+
): TronTransactionPayload | undefined {
|
|
39
|
+
const rawData = transaction.raw_data as
|
|
40
|
+
| { contract?: TronRawDataContract[] }
|
|
41
|
+
| undefined;
|
|
42
|
+
const call = rawData?.contract?.[0]?.parameter?.value;
|
|
43
|
+
|
|
44
|
+
if (!call?.data || !call.owner_address || !call.contract_address) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
type: 'WEB',
|
|
50
|
+
owner_address: call.owner_address,
|
|
51
|
+
call_value: 0,
|
|
52
|
+
contract_address: call.contract_address,
|
|
53
|
+
fee_limit: feeLimit,
|
|
54
|
+
function_selector: APPROVE_FUNCTION_SELECTOR,
|
|
55
|
+
parameter: call.data.slice(FUNCTION_SELECTOR_HEX_LENGTH),
|
|
56
|
+
chainType: null,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The wallet-injected TronWeb instance, or a readable error when absent. */
|
|
61
|
+
export function getTronWeb(
|
|
62
|
+
instance: () => ProviderAPI | undefined
|
|
63
|
+
): TronWebApi {
|
|
64
|
+
const tronInstance = instance();
|
|
65
|
+
if (!tronInstance?.tronWeb) {
|
|
66
|
+
throw new Error('Tron is not available on your wallet.');
|
|
67
|
+
}
|
|
68
|
+
return tronInstance.tronWeb;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Tron mainnet address prefix byte (0x41) in hex. */
|
|
72
|
+
const TRON_HEX_ADDRESS_PREFIX = '41';
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Prerequisite addresses arrive in 0x-hex (EVM-style) form; TronWeb expects a
|
|
76
|
+
* Tron address. Convert `0x<20-bytes>` → `41<20-bytes>` → Base58.
|
|
77
|
+
*/
|
|
78
|
+
export function hexAddressToTronBase58(
|
|
79
|
+
tronWeb: TronWebApi,
|
|
80
|
+
address: string
|
|
81
|
+
): string {
|
|
82
|
+
const tronHex = TRON_HEX_ADDRESS_PREFIX + address.replace(/^0x/, '');
|
|
83
|
+
return tronWeb.address.fromHex(tronHex);
|
|
84
|
+
}
|
|
85
|
+
|
|
12
86
|
export function formatAccountsToCAIP(accounts: string[]) {
|
|
13
87
|
return accounts.map(
|
|
14
88
|
(account) =>
|